这是C++算法基础-数据结构专栏的第三十三篇文章,专栏详情请见此处。
引入
在最开始,我们学习了快速排序和归并排序,它们都是很优秀的算法,而今天学习的堆排序,是使用数据结构堆来实现的。
下面我们就来讲堆排序的实现。
定义
堆排序是使用数据结构堆来实现的一种排序算法。
过程
堆排序的思路很简单,一共4步(以从小到大排序为例):
- 将待排序序列构造成一个大根堆。
- 此时,整个序列的最大值就是堆顶的根节点,将其与末尾元素进行交换,此时末尾就为最大值。
- 然后将剩余元素重新构造成一个堆,这样会得到所有元素的次小值。
- 如此反复执行第二步、第三步,元素的个数逐渐减少,循环
次,便能得到一个有序序列了。
具体来说,第一步,我们依次插入数据并调整,调整的时候,我们从倒数第二层的第一个根和其子节点开始,因为子节点不需
;第二步,把根节点的值与末尾元素的值进行交换,此时,我们需要一个存储右边界的变量
,将
,防止在下一步中重新处理刚刚交换后的值;第三步,重新处理堆顶,使用上次学过的
函数;第四步,循环处理。
其实,包括上一节课,有些时候我们会将某一位置的值与末尾元素的值进行交换再调整,例如删除某一节点。其实,原因很简单,就是因为我们不能直接操作某一位,这样有可能出现错误,而末尾元素是很好操作的,因为它的后面没有元素,这样,我们就间接执行了操作。这一方法在实现各种数据结构的时候很有帮助,相信看过我之前的文章的人深有体会。
代码实现中,我不再呈现函数以及在上篇文章中讲解并呈现的操作,只呈现堆排序特有的操作。
代码
下面给出堆排序的实现代码:
int n,r;
for(int i=n/2;i;i--) down(i);
while(m--){
printf("%d ",h[1]);
h[1]=h[cnt--];
down(1);
}
代码解释
第一行是堆的大小的和右边界变量;for循环中是将插入数据调整;while循环中是堆排序的主体内容。
上一篇-堆的实现 C++算法基础专栏文章 下一篇-哈希表的实现
每周六更新一篇文章,内容一般是自己总结的经验或是在其他网站上整理的优质内容
点个赞,关注一下呗~