当前位置: 首页 > news >正文

堆排序-Head Sort

堆排序

堆的定义

堆是具有下列性质的完全二叉树:每个结点的值都小于或等于其左右孩子终点的值(小根堆)或者每个结点的值都大于或等于左右结点孩子的值(大根堆)

v4eX6O.png

堆排序要解决的关键问题

  1. 如何将一个无序的序列构造成一个堆(即初始建堆)

    1. 无序序列建堆是一个反复筛选的过程。因此序列就是一颗完全二叉树的顺序存储,则所有的叶子结点也是堆,所以只需要从 最后一个分支结点开始执行筛选过程直到根节点
  2. 如何处理堆顶记录

  3. 初始建堆之后,将待排序序列分成无序区和有序区两个部分,其中无序区为堆,且包括全部待排序记录,有序区为空。将堆顶与堆中最后一个记录交换,则堆中减少了一个记录,有序区增加了一个记录。

  4. 如何调整剩余记录,成为一个新的堆(即重新建堆)

    1. 第i趟排序后,无序区有n-i个记录,在无序区对应的完全二插树只需要筛选根结点即可重新建堆。

筛选思路

  1. 设置i和j分别指向当前要筛选的结点和要筛选结点的左孩子
  2. 若结点i已经是叶子,则筛选完毕,算法结束;否则执行下述操作
    1. 将j指向结点i的左右孩子中的较大者
    2. 如果r[i]>r[j],则筛选完毕,算法结束
    3. 如果r[i]<r[j],则将r[i]与r[j]交换,令i=j,转步骤二继续筛选

树以数组形式存储–其对应的下标关系

假设n为根结点:其左子树为2n,其右子树为 2n+1

堆排序

//
// Created by HANWENKE on 2022/8/31.
//
#include <iostream>
#include <vector>
using namespace std;
void Shift(vector<int>&nums,int len,int i){
    int index=2*i+1;
    while(index<len){
        if(index+1<len){
            if(nums[index+1]<nums[index]){
                index++;
            }
        }
        if(nums[index]<nums[i]) {
            int temp = nums[i];
            nums[i] = nums[index];
            nums[index] = temp;
            i = index;
            index = 2 * i + 1;
        }else{
            break;
        }
    }
}
void HeapSort(vector<int>&nums,int n){
    for(int i=n/2-1;i>=0;i--){
        //初始化建堆
        Shift(nums,n,i);
    }
    for(int i=n-1;i>0;i--){
        //依次调整--将最大的调整到最上面
      int temp=nums[i];
      nums[i]=nums[0];
      nums[0]=temp;
      Shift(nums,i,0);
    }
}
int main(){
    vector<int>arr;
    arr.reserve(20);
    for(int i=0;i<50;i++){
        arr.push_back(rand()%1000);
    }
    for(int i=0;i<arr.size();i++){
        cout<<arr[i]<<" ";
    }
    cout<<endl;
    HeapSort(arr,arr.size());
    for(int i=0;i<arr.size();i++){
        cout<<arr[i]<<" ";
    }
    return 0;
}

相关文章:

  • 【C++】wav文件解析(兼容性强)
  • 免费查题接口搭建
  • 多目标优化算法|用于全局和工程设计优化的多目标原子轨道搜索 (MOAOS)算法(Matlab代码实现)
  • [C++]:for循环for(int num : nums)
  • 3年测试经验,去面试连25K都拿不到了吗?现在测试这么坑?
  • 网课查题公众号 免费授权搜题接口
  • 一篇文章搞懂java中类以及static关键字执行顺序
  • 新手设计师一定要逛这几个网站
  • 多目标优化算法|基于拥挤距离的有效多目标人工蜂鸟算法,用于解决工程设计问题(Matlab代码实现)
  • yara分析
  • 早上一上班发现产品出现重大事故,作为产品经理该怎么办?
  • PaddleHub开源模型400+,三行代码也可实现无限AI创意梦想!
  • [Linux] CE知识随笔含Ansible、防火墙、VIM、其他服务
  • java架构知识点-中间件
  • 基于SSM的视频管理系统【完整项目源码】
  • [nginx文档翻译系列] 控制nginx
  • 【Leetcode】104. 二叉树的最大深度
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 【知识碎片】第三方登录弹窗效果
  • 2017届校招提前批面试回顾
  • 230. Kth Smallest Element in a BST
  • CSS居中完全指南——构建CSS居中决策树
  • Js基础知识(一) - 变量
  • js作用域和this的理解
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • php的插入排序,通过双层for循环
  • React的组件模式
  • TCP拥塞控制
  • vue--为什么data属性必须是一个函数
  • 关于springcloud Gateway中的限流
  • 计算机在识别图像时“看到”了什么?
  • 记一次用 NodeJs 实现模拟登录的思路
  • 免费小说阅读小程序
  • 如何利用MongoDB打造TOP榜小程序
  • 我感觉这是史上最牛的防sql注入方法类
  • 译米田引理
  • 再谈express与koa的对比
  • puppet连载22:define用法
  • ​​​​​​​​​​​​​​Γ函数
  • #AngularJS#$sce.trustAsResourceUrl
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (六)软件测试分工
  • (小白学Java)Java简介和基本配置
  • (转)程序员疫苗:代码注入
  • (转载)OpenStack Hacker养成指南
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验