今天来看一个比较复杂的排序,堆排序,先搞清楚原理,再写代码。
堆排序使用数据结构中的堆来完成,那么问题来了,什么是堆?
有两种,大顶堆和小顶堆,所谓大顶堆,就是任意一个双亲节点都比孩子节点大,比如图上这样的,小顶堆则反过来。
所以对于大顶堆来说,根节点一定是最大的。
比如有这样一个数组,先把它画成一颗二叉树的形式,接下来就是构建大顶堆,这个部分也是整个堆排序中最耗时的部分。
从0这个节点开始,因为节点0是最后一个有孩子的节点。
0比2小,交换一下位置。
再轮到4,8和9比较,显然是9大,把9和4交换一下位置。
最后轮到3,9比2大,9和3需要交换一下位置。
注意,因为这个节点发生了变化,所以3 8 4不再满足条件,还得继续调整。8比4大,8和3交换一下位置。
这个过程就是构建大顶堆。
于是,我们得到了最大的数字9,把它和最后一个数字做交换,然后断开,意思就是后面的操作跟9没有关系了。
接下来就是调整大顶堆,不需要再像刚才那样构建,因为这颗二叉树也只有根节点被修改了。
0和8交换,4和0交换,又得到了第二大的数字8。
不断的重复,最后就是一个有序的序列。
写代码之前,还得明确一个问题,虽然我们一直在操作二叉树,但是写代码的时候并不需要真的去创建一颗二叉树,我们只是在操作数组的下标,比如下标为n的节点作为根几点,那么他的左孩子就是 2n+1,右孩子就是2n+2。
#include void adjust_heap_sort(int *a, int root, int last){ int child; while (1) { child = 2 * root + 1; if (child > last) break; if (child + 1 = 0; i--) { adjust_heap_sort(a, i, size - 1); } //调整大顶堆 for (int i = size - 1; i > 0; i--) { int num = a[0]; a[0] = a[i]; a[i] = num; adjust_heap_sort(a, 0, i - 1); }}int main(){ int array[] = {3, 4, 0, 8, 9, 2}; heap_sort(array, 6); for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++) { printf(%d , array[i]); } printf(); return 0;}代码确实不太容易理解,不过在这些排序算法中,越是不容易理解的,效率也就越高,还是用它和冒泡做个对比,10000个数据,差距还是很大的。root@turbo:test# time ./heap_sort real 0m0.005suser 0m0.004ssys 0m0.000sroot@turbo:test# time ./bubble_sort real 0m0.606suser 0m0.554ssys 0m0.000sroot@turbo:test#
【蜂窝物联】智慧粮仓环境在线监测系统
东方集成与RIGOL签署DSA1000系列全国唯一平台经销商协议
比亚迪电池分拆和独立过程中的一些核心要点
网友吐槽iPhone 12 mini拍照的不足
二手车流通市场中 插混车保值率比纯电动车高
难度系数最高之堆排序简介
几种灭菌方法对医疗器械元件的影响
ZigBee与其它短距离无线通信技术对比分析
单片机晶振又是什么呢?单片机中若是没有了晶振会怎么样呢?
如何实现一个简单的FM调频发射制作实验
是德安捷伦Agilent8720ES网络分析仪
中国电信利用5G+天翼云的云网融合优势建成“2+31+X”云网基础设施
LTE使移动网络E2EVoIP成为现实
为什么正激式开关电源电路只能降压,而反激式既可降压又可升压?
启辉器在日光灯中的效果及日光灯启辉器的拆装图解
工业机器人的组成部分
自动气象站的应用优势是怎样的
Avago推出WiFi接入点前端模块AFEM-S105
《工业互联网边缘计算安全白皮书(2020)》正式发布
信用钱包怎样协助人工智能的发展