内部排序 ——第4波——————【堆排序】
2016-04-07 20:21
323 查看
堆排序基本思想:首先建立一个大根堆。将第一大的值输出来,用最后一个值去替换第一大值的位置,然后进行筛选,重新得到一个堆,得到n个元素的次大值。如此反复执行,得到一个有序序列,这个过程称为堆排序。
建堆:对于一个n个元素的序列,从下标为floor(n/2)这个元素开始,直到1,对每个元素进行筛选,筛选完后,即可保证以该元素为根的子树是一个堆。
时间复杂度:堆排序在最坏情况下的时间复杂度也为O(nlogn)
空间复杂度:O(n)。
建堆:对于一个n个元素的序列,从下标为floor(n/2)这个元素开始,直到1,对每个元素进行筛选,筛选完后,即可保证以该元素为根的子树是一个堆。
时间复杂度:堆排序在最坏情况下的时间复杂度也为O(nlogn)
空间复杂度:O(n)。
//堆排序 #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; const int maxn = 1e3+200; struct Heap{ int key; }heap[maxn]; void HeapAdjust(int s,int m){ //堆调整 Heap rt = heap[s]; //记录开始的节点 for(int i = s*2; i <= m; i *= 2){ if(i < m && heap[i].key < heap[i+1].key) i++; //比较左右子节点大小 if(heap[i].key < rt.key) break; //如果最大的子节点没有rt的值大,结束 heap[s] = heap[i]; s = i; } heap[s] = rt; } int main(){ int n; while(scanf("%d",&n)!=EOF){ for(int i = 1; i <= n; i++){ scanf("%d",&heap[i].key); } for(int i = n/2; i >= 1; i--){ //最后一个非终端节点floor(n/2) HeapAdjust(i,n); } for(int i = 1; i <= n; i++){ printf("%d %d\n",i,heap[i].key); }puts(""); for(int i = n; i >= 2; i--){ printf("%d ",heap[1].key); swap(heap[1],heap[i]); HeapAdjust(1,i-1); }printf("%d\n",heap[1]); for(int i = 1; i <= n; i++){ printf("%d %d\n",i,heap[i].key); }puts(""); } return 0; }
相关文章推荐
- jq 设置和获取元素内容和属性
- 剑指offer-面试题12.打印1到最大的n位数
- AndroidStudio插件GsonFormat
- ios开发中的一些注册流程的Check
- ACM内部函数--数学问题--大数阶乘
- J2EE SDK安装报错could not find the required version of the Java(TM)2 Runtime Environment in '(null)'
- IOS开发基础知识--碎片36
- lua的Metatables和Metamethods
- Android——适配器其他组件(AutoCompleteTextView:自动完成文本编辑框;Spinner:下拉列表)
- POJ1743(后缀数组)
- 剑指offer-面试题11.数值的整数次方
- 立体最短路径,广搜(POJ2251)
- B/S/S 和 C/S/S
- 标准差公式的变形
- 优秀程序员应具备的5项基本素质
- 今天主要是在项目上进行一个健康档案的改进
- 【前端性能】浅谈域名发散与域名收敛
- C++单向链表之删除节点
- Linux写时拷贝技术(copy-on-write)
- Makefile 脚本小列举