堆排序(大根堆与小根堆)
创始人
2024-03-19 18:50:04

(1)是什么?

是一种适用于关键字较多的情况下的排序算法,例如在十亿个数中选出前1000个最大值或者最小值
如果在传统的排序算法中(例如冒泡,插入等),我们习惯把目标数据整体进行一次排序,再截取出前1000个最小的或者最大的。
但是我们可以设想一下,从一开始我们目标就只要1000个,那么其实其余九亿九千九百九十九万九千个数据,我们压根不需要知道它们的排序顺序,只需要知道它们都比我们1000个目标数据中最大值都要大就可以了
这就是堆排序。

它的思想整体上非常清晰简单,结构上是一个完全二叉树。
根结点比左右孩子都大则叫做大根堆。其中,左右孩子的根结点,又会比它们的左右孩子都大。
根结点比左右孩子都小则叫做小根堆。其中,左右孩子的根结点,又会比它们的左右孩子都小。
更简单点说:所有中间结点,一定比它孩子大(大根堆),或者一定比它的孩子小(小根堆)

(2)如何构建大根堆

初始化:

1:按照给出的数组,首先按照层次优先(逐层摆放)构造一棵二叉树
2:从该二叉排序树的最后一个叶子结点的根结点出发,比较该结点的左右孩子,选取最大的置换到根结点上
3:整理倒数第二非叶子结点,比较并选择一个最大的置换到根结点…
4:依次类推,直到整理完整棵树,此时树的根结点一定是该大根堆中最大值
5:在把大数往上顶的过程中,也要看互换位置的数是否比左右孩子都大,如果不是,则又要选择一个最大的换到该子树根结点。

例如:假设有数组【1,3,5,7,9,2,4,6,8,10】要求建立大根堆

1:先按照层次优先原则建立二叉树(该树生成后默认按照行遍历存放在一个一维数组中,且该数组下标从1开始,即下标为1存放着根结点1,下标2存放左孩子2,下标3存放着右孩子5,以此类推)
在这里插入图片描述

2:从该二叉树的最后一个非叶子结点出发,比较该结点的左右孩子,选取最大的置换到根结点上
如何找到二叉树最后一个非叶子结点:n/2向下取整
该例子中,10个元素,则10/2 = 5;即最后一个非叶子结点下标是5,也就是根结点值为9的子树。
比较9,10,发现10最大,于是10和9交换位置。

3:整理倒数第二非叶子结点,比较并选择一个最大的置换到根结点…
如何找到倒数第二个非叶子结点:n/2 - 1 = 4
也就是下标为4的,根结点值为7的子树
比较6,7,8,于是7和8交换位置,8作为根结点。

4:依次类推,直到整理完整棵树,此时树的根结点一定是该大根堆中最大值
5:在把大数往上顶的过程中,也要看互换位置的数是否比左右孩子都大,如果不是,则又要选择一个最大的换到该子树根结点。
在这里插入图片描述

到这里就完成了大根堆的构建

输出栈顶元素:

当输出栈顶的10后,固定用【最后一个叶子结点】1补上,发现1破坏了大根堆的性质,于是要从根结点往下调整,也就是比较1,9,5;把9放根结点。
1下沉到左子树根结点,但是还是不满足大根堆性质,于是比较1,8,3;把8放到左子树根结点,1再次下沉到左子树的左子树的根结点中
比较1,6,7;把7替换到左子树的左子树的根结点,把1再次下沉。
至此,重新调整的二叉树又符合大根堆性质了。
在这里插入图片描述

新增/插入元素操作:

新增/插入的元素都是把新结点放在新生成的最后一个叶子结点中,然后比较该新叶子结点数据的值与它父结点的值的大小,看是否需要换位置,如果需要,则开始调整,这跟初始化时候一样的操作。

⚠️注意,初始化和新增元素都是由下至上的调整,而删除了栈顶元素,是由上至下的调整。

代码实现:

#include void HeapSort(int a[], int i, int lenght){/*用以保存子树的根结点*/a[0] = a[i];/* 按照二叉树性质,不断i*2是不断深入找到下一层的左孩子结点 */for(int j=i*2; j<=lenght; j=j*2){/* k是对应子树的右孩子结点,先比较右孩子 */int k = j+1; /* 左右孩子比较出一个大值 */if(ka[j]){j = k;}/* 判断根结点与左右孩子的最大值谁更大 */if(a[0]a[i] = a[j];i = j;}}/* 循环退出后,j一定是最适合temp值的地方 */a[i] = a[0];
}int main()
{int a[]={0,1,3,5,7,9,2,4,6,8,10};int lenght = 11;/* 从下往上逐个非叶子结点调整 */for(int i=lenght/2; i>0; i--) {HeapSort(a,i,lenght);}return 0;
}

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...