图解堆排序(一次弄懂堆结构以及堆排序)

简介: 图解堆排序(一次弄懂堆结构以及堆排序)

前言:

我们知道研究一个数据结构自然要研究它的逻辑结构物理结构,其中逻辑结构是我们真正关注的,因为一个数据结构是否优秀,它的各类操作的核心思想都是由逻辑结构决定的,而物理结构仅仅是去适应逻辑结构。而堆排序用到了堆这个数据结构,所以我们就先来研究一下堆的这两个结构。

堆的逻辑结构:

1、树结构的一种变形,是完全二叉树。树结构同样也是逻辑结构下的一种数据结构

2、满足“每个节点都大于等于其父节点(根节点除外)”的堆称为最小堆

3、满足“每个节点都小于等于其父节点(根节点除外)”的堆称为最大堆

具体图见下:

左边为大根堆,右边为小根堆

堆的物理结构:

物理结构探究的就是如何把这个逻辑结构在真实的计算机内存空间中存储下来。这个存储必须要能体现逻辑结构所有的一切逻辑特征。

常见的物理结构就是链表(随机存储)、数组(顺序存储)。对于堆和树,我们采取的物理结构往往是数组存储。然后通过下标去体现树的逻辑结构。

例如上面的小根堆和大根堆的对应的数组存储方式如下:

总的来说就是利用树的层次遍历的顺序一一把结点放到数组当中 。

堆排序用到树的一些性质(树堆相同):

1、令x为根节点下标,则x*2为其左子树下标,x*2+1为其右子树下标

2、最后一排叶子节点的个数为总节点数的一半

3、存储从数组下标1开始,若是0开始上面两条性质会改变。

堆结构基础操作方法:

1、heap数组就是存储树结构各节点的数组

2、size就是整个数组的长度,也是堆的节点数

3、当一个堆因加入、修改、删除等操作出现一个节点发生改变,小于原本的节点时,整体堆可能不再满足其堆的性质,这个时候就要通过down操作,把该节点通过逐级下沉(若是小根堆则要逐级上浮,用up函数),放到其应该在的位置,使整体结构仍满足堆的性质。

所以在堆的问题中最难的地方在于down和up两个操作

down操作:

down顾名思义就是把一个元素下沉到它应该在的地方。对应环境:小根堆中,一个元素值变大了,就要考虑下沉。或者大根堆中,一个元素值变小了,就要考虑下沉。

具体的步骤如下:(小根堆为例子)

1、定义一个变量t表示待调整数x应该在的位置,开始时赋值为x的初始位置,即t=x。

2、先将x与其左子树比较大小(即num[t] 比较 num[x/2]),如果比左子树要大,则将t赋值为左子树的位置(即t=x/2)。表示目前x应该在左子树这个地方。

3、再将t的值与右子树比较(即num[t] 比较 num[x/2+1]),如果目前t位置(x目前应该在的位置)的值大于右子树的值,那么说明x有更优的解,故将t=x/2+1。

(2,3步骤的本质就是找到x左右子树中较小的那一个,因为x就是要和较小值交换)

4、最后如果t和x不相等,则交换两者的位置。

图解如下:(小根堆为例子)

说明:1、图中27先于15、19中较小的15交换,完成第一轮下沉

2、再与18、28中的18交换,完成第二轮下沉。

3、之后,再不停重复这两个操作。直到27比下面两者都小或到达叶子结点为止。

up操作

up操作顾名思义就是把一个元素不停上浮到它应该在的地方。对应环境是:小根堆中,一个根节点元素值比原本要小了,就要考虑是否需要上浮。或者大根堆中,一个根节点变大了,就要考虑上浮

具体步骤如下:(选取小根堆为例子,大根堆的话要相反)

1、与根节点比较,如果小于根节点,则上浮。

2、再与下一层根节点比较,如果仍然小于则继续上浮

3、直到到达最上方,或不再小于根节点为止

图解如下:(大根堆为例子,让大家两种情况都看看)

堆排序:

了解完堆的基本操作就让我们来看看,这个利用堆结构特点来操作的排序算法。

对于小根堆:

1、将元素随意放到一个堆中,再对堆进行初始化,使其从杂乱状态变为小根堆

2、取出其顶部元素,自然就是整个堆中的最小值。

3、然后再把最尾部的元素上移到根节点,这个尾部元素自然很大,所以在对这个元素执行down操作,从而使堆重新变为小根堆的结构。

4、不停重复1 2操作直到全部取出元素。自然形成由小到大的序列

对于大根堆:

1、将元素随意放到一个堆中,再对堆进行初始化,使其从杂乱状态变为大根堆

2、取出其顶部元素,自然就是整个堆中的最大值。

3、然后再把最尾部的元素上移到根节点,这个尾部元素自然很小,所以在对这个元素执行down操作,从而使堆重新变为大根堆的结构。

4、不停重复1 2操作直到全部取出元素。自然形成由大到小的序列

注意:堆排序算法并没有用到up操作

图解堆排序:

上图就体现了从取出元素到调整新的有序堆的全过程 ,大家好好琢磨肯定能明白的!

画图不易,大家给个免费的赞呗。如果觉得写的不错,也可以按下可爱的五角星收藏

堆排序完整代码如下:

#include<iostream>
using namespace std;
const int n=100001;
void down(int x,int a[],int num){
    int k=x;
    if(x*2<=num&&a[x*2]<a[k])k=x*2;
    if(x*2+1<=num&&a[x*2+1]<a[k])k=x*2+1;//首先判断是否存在左右子树再进行判断,否则会造成非法空间访问
    //交换并进入下一层递归
    if(a[k]<a[x]){ 
        swap(a[k],a[x]);//交换值
        down(k,a,num);//下次从a[x]所在的新的位置继续向下down
    }//如果a【x】的值此时已经小于左右子树中的最小值,那么直接放置并且退出循环即可
    
}
int main(){
    int num,k;//num表示总共有多少待排序的数,k表示要输出前k个数
    int a[n];
    cin>>num>>k;
    for(int i=1;i<=num;i++){//从1开始,为了方便下标计算
        cin>>a[i];
    }
    //初始化小根堆。从小到大就是小根堆,反之就是大根堆.时间复杂度为O(n)
    for(int i=num/2;i>0;i--){
        down(i,a,num);
    }
    //初始化后开始堆排序
    for(int i=1;i<=k;i++){
        cout<<a[1]<<" ";//这里第一次错了,debug40分钟
        a[1]=a[num--];
        down(1,a,num);
    }
    return 0;
}
相关文章
|
存储 算法
【堆】数据结构堆的实现(万字详解)
【堆】数据结构堆的实现(万字详解)
770 0
|
监控 API UED
Elasticsearch 异步搜索 Async search 实战
1、Elasticsearch 异步搜索定义 异步搜索 API 可异步执行搜索请求、监控其进度并检索可用的部分结果。 如下的官方介绍动画,能更加生动的介绍清楚异步检索。 传统检索 VS 异步检索,在数据量比较大时: 传统检索可能导致超时,以至于无数据返回;或者需要等待很久,用户体验差。 异步检索,可以快速响应数据,用户无需等待。
Elasticsearch 异步搜索 Async search 实战
|
存储 搜索推荐
【七大排序】堆排序详解
【七大排序】堆排序详解
621 3
|
存储 机器学习/深度学习 人工智能
数据结构学习笔记——图的存储结构(邻接矩阵和邻接表)
数据结构学习笔记——图的存储结构(邻接矩阵和邻接表)
数据结构学习笔记——图的存储结构(邻接矩阵和邻接表)
|
9月前
|
安全 搜索推荐 Android开发
Android系统SELinux安全机制详解
如此看来,SELinux对于大家来说,就像那位不眠不休,严阵以待的港口管理员,守护我们安卓系统的平安,维护这片海港的和谐生态。SELinux就这样,默默无闻,却卫士如山,给予Android系统一份厚重的安全保障。
330 18
|
前端开发 开发者
鸿蒙next版开发:相机开发-元数据(ArkTS)
在HarmonyOS 5.0中,ArkTS新增了对相机元数据的访问能力,帮助开发者获取图像的详细信息。本文介绍了如何在ArkTS中获取和使用相机元数据,包括导入接口、创建元数据输出流、开启和停止元数据输出、监听元数据对象可用事件等步骤,并提供了详细的代码示例。
277 5
|
机器学习/深度学习 人工智能 数据可视化
小滑块上个斜面,难倒多少高中生?现在,AI让它动起来了
《Augmented Physics:基于机器学习的物理学习工具》 高中物理学习中,小滑块上斜面等问题常让学生困惑。Augmented Physics利用AI技术,将静态物理图示转化为交互式模拟,通过增强实验、动画图示、双向操作和参数可视化等技术,帮助学生直观理解物理概念。研究表明,该工具能有效提升学生对物理概念的理解,具备广阔的应用前景。
327 1
|
存储 Java
Java 链接表(链表)详解与实现
Java 链接表(链表)详解与实现
568 2
|
存储 人工智能 文字识别
2024年看AIGC是如何让1688主图焕发新春的
本文主要向大家系统地介绍了1688严选和商品品质化之旅。从买家心智和业务诉求中的痛点与机会到整体的方案和集体上线时的数据和效果,希望进一步提升严选商品的表达和买家转化。
|
存储 JavaScript 小程序
高德地图实现点聚合功能的详细步骤加截取地图图片 (附源码)
高德地图实现点聚合功能的详细步骤加截取地图图片 (附源码)
1351 0