排序算法五——堆排序
来源:互联网 发布:ps3验证游戏数据 编辑:程序博客网 时间:2024/05/18 02:02
排序算法五:堆排序
其实堆排序本质上也是选择排序,只不过选择的方法不一样。直接选择排序法是将第一个数字与后面所有数字比较,然后找到最大(或最小)的值,然后swap交换,这样第一个数字就是最大(或最小)的数字了。然后再将第二个数与剩下的所有数字比较,找到第二大(或第二小)的数字,然后交换。就这样依次选择下去,就排好序了。
那么堆排序其实跟选择排序一样,每次把最大值(或最小值)找到,找的方式是通过构建“大顶堆”或“小顶堆”来实现的,堆的最上方(树的根)一定是树的最大值(或最小值),然后将树的根与最后一个数字swap调换,然后再将剩下的数字构造为大顶堆,构建完成后再将树的根与倒数第二个数字swap调换,然后再把剩下的数字构建大顶堆,然后再调换…… 最后数字就排好序了。
根排序是不稳定的排序,因为他数字跳来跳去,换来换去。跳跃式的比较跟交换。(我知道你不知道这句话什么意思)。
这是我自己画的图,有点丑:
这个图很明显能看出,我是从0开始的,不是从1开始。
树有一个性质,就是左子树的编号是双亲编号的两倍(2*n),当然我这里编号是从0开始的,左子树的编号是双亲编号的两倍再加1(2*n + 1).
算法大概就是是先初始化大顶堆,然后再调换根与最后一个数字,然后再调整大顶堆,再调换,在调整……
你们自己看代码吧。
堆排序代码:
/***************************************************** File name:5heap_sort.c Author: Tang Zhiqian Date:2017-08-08 16:36*****************************************************/#include <stdio.h>#define MAX 10typedef int ElementType;typedef ElementType ARR[MAX];ARR arr = {10,5,1,6,2,7,3,8,4,9};int len = sizeof(ARR)/sizeof(ElementType);void HeapSort(ARR arr);void swap(int arr[],int i,int j);void HeapAdjust(ARR arr,int s,int max); //调整为大(小)顶堆void print(ARR arr);int main(){ printf("排序前:\n"); print(arr); HeapSort(arr); printf("堆排序后:\n"); print(arr); return 0;}void HeapSort(ARR arr){ int i; for (i = (len-1)/2; i > 0; i--) //从最后一个非叶子节点开始 ★ { HeapAdjust(arr,i,len-1); } for (i = len - 1; i > 0; i--) { swap(arr,0,i); //跟最后一个调换 HeapAdjust(arr,0,i - 1); //重新调整为大顶堆 }}void HeapAdjust(ARR arr,int s,int max){ int temp = arr[s]; //记录根的值 int i; for (i = 2*s + 1; i <= max; i = 2*s + 1) //从根节点的左孩子开始往下循环 { if (arr[i + 1] > arr[i] && i < max) //如果右孩子大于左孩子,i++,i变为右孩子下标 { i++; } if (temp >= arr[i]) //如果根节点值是最大的,那就跳出循环 { break; } arr[s] = arr[i]; //到这步说明根节点不是最大的,让根节点等于大的值 s = i; //记录贡献出值的位置 } arr[s] = temp; //循环结束,把贡献出值的位置赋值temp}void swap(int arr[],int i,int j){ ElementType temp; temp = arr[i]; arr[i] = arr[j]; arr[j] = temp;}void print(ARR arr){ int i; for (i = 0; i < len; i++) { printf("%d ",arr[i]); } printf("\n");}
我觉得代码里面注释的还比较清楚,可能只有我自己能看懂((●’◡’●))
程序运行结果:
美滋滋!没毛病!
关于堆排序的时间复杂度,平均时间复杂度O(nlogn)。他也突破了O(n^2).空间上也只用到一个temp,美滋滋!
阅读全文
1 1
- 排序算法五——堆排序
- 排序算法—堆排序
- 排序算法—堆和堆排序
- 排序算法——堆排序算法
- 内部排序(五)堆排序算法
- 蛙步学排序算法之五 - 堆排序
- 排序算法(五)堆排序
- Java排序算法(五):堆排序
- 算法学习(排序五)堆排序
- 排序算法——堆排序
- 排序算法——堆排序
- 常用排序算法——堆排序
- 排序算法——堆排序
- 排序算法——堆排序
- 算法——排序之堆排序
- 排序算法——堆排序
- 排序算法——堆排序
- 排序算法——堆排序
- 关于递归的总结——汉诺塔、素因数的求解(Python实现)
- 2.多级菜单
- HDU6092 Rikka with Subset【DP】
- 关于AndroidStudio的快捷键使用
- CodeForces
- 排序算法五——堆排序
- 8.9上课感悟
- 接口作为类型使用
- Lintcode103 Linked List Cycle || solution 题解
- Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)
- Mysql 练习题 加Mysql的表
- 【51nod 教程】矩阵取数问题(动态规划)
- 渐进增强和优雅降级之间有什么不同?
- 如何用SpringBoot框架来接收multipart/form-data文件