堆排序
2015-07-16 19:41
225 查看
//堆排序的根据是什么,就是每个堆的顶部的元素一定是最小值,那么我先建一个堆,每次记录下堆顶元素,然后把重新排列(这里有点技巧),减少堆的元素个数。
//注意堆的n是会变化,所以要先记录下来。
//处于同一层的节点大小不能判断,所以每次提取了堆顶元素就必须重新维护一次。(代码在sort部分)
//这种方式无法用原来数组来保存元素,即是在原来的堆上进行修改得到的数据,那么有没有一种结果本身就是用堆来保存的从小到大的方法呢
//第二种方法就是先建立最大堆,则堆顶元素一定为当前堆内的最大元素,把它放在堆尾,并n--,使其不会改变,接着如法炮制,找出第二大,第三大元素。。,直到只剩一个元素
//该方法最后得到的是堆内按照下标顺序,已经是从大到小有序的,而不是第一种方法,边输出,边找下一个元素,因而在某些特定要求下会更加方便~~
//注意堆的n是会变化,所以要先记录下来。
//处于同一层的节点大小不能判断,所以每次提取了堆顶元素就必须重新维护一次。(代码在sort部分)
#include <stdio.h> int a[101]; int n; void down(int i) { int temp,t; while(i*2<=n) { if (a[i]>a[i*2]) t=i*2; else t=i; if ((i*2+1<=n)&&(a[t]>a[i*2+1])) t=i*2+1; if (t!=i) { temp=a[t]; a[t]=a[i]; a[i]=temp; i=t; } else break; } return; } int sort() { int t; t=a[1];//每次先记录下堆顶的元素 a[1]=a ;//修改堆顶的元素,再对堆进行整理 n--;//注意是先将元素个数减少一个,再维护(因为此时第一个元素已经被拿出,换成了最后一个元素,即原本最后一个元素的位置不需要了) down(1); return t; } int main() { int i,num; scanf("%d",&n); num=n;//注意了这里的n是会变化的,所以要先记录下n的值(好吧,我查了好久才找到错这~~) for (i=1;i<=n;i++) scanf("%d",&a[i]); for (i=n/2;i>=1;i--) down(i); for (i=1;i<=num;i++) printf("%d ",sort()); printf("\n"); return 0; }
//这种方式无法用原来数组来保存元素,即是在原来的堆上进行修改得到的数据,那么有没有一种结果本身就是用堆来保存的从小到大的方法呢
//第二种方法就是先建立最大堆,则堆顶元素一定为当前堆内的最大元素,把它放在堆尾,并n--,使其不会改变,接着如法炮制,找出第二大,第三大元素。。,直到只剩一个元素
//该方法最后得到的是堆内按照下标顺序,已经是从大到小有序的,而不是第一种方法,边输出,边找下一个元素,因而在某些特定要求下会更加方便~~
#include <stdio.h> int a[101]; int n; void down(int i) { int temp,t; while (i*2<=n) { if (a[i]<a[i*2]) t=2*i; else t=i; if ((i*2+1<=n)&&(a[t]<a[i*2+1])) t=2*i+1; if (t!=i) { temp=a[t]; a[t]=a[i]; a[i]=temp; i=t; } else break; } } void sort() { int temp; while (n>1) { temp=a ; a =a[1];//此时堆顶元素就是最大值 a[1]=temp;//因此将堆顶元素与最后一个元素交换 n--;//最后一个元素已经确定(位置是正确的),只需再对前n-1个数进行同样的考察 down(1); } } int main() { int i,num; scanf("%d",&n); num=n;//同样要先记录下n for (i=1;i<=n;i++) scanf("%d",&a[i]); for (i=n/2;i>=1;i--) down(i);//建立最大堆 sort(); for (i=1;i<=num;i++) printf("%d ",a[i]); return 0; }
相关文章推荐
- eclipse最有用快捷键整理_quick code
- 二分图最大匹配(匈牙利算法) UVA 10080 Gopher II
- 使用四种框架分别实现百万websocket常连接的服务器
- POJ 1293 Duty Free Shop
- openlayers3添加地图控件
- 【高级算法】单纯形法求解线性规划问题(C++实现)
- Javascript之第三方程序库
- [字符串] 一个巧妙的字符串循环移位法
- opencv cvSplit cvMerge
- 组合数学+整数分解 POJ 2992 Divisors
- UVALive 4253 Archery(二分+atan2应用)
- HTML5第三弹:亦酷亦萌的网络拓扑图
- 关于NSString的练习题
- SpringMVC——接收请求参数和页面传参
- ZigZag Conversion
- HDU 5113 Black And White(DFS+剪枝)
- Hadoop map任务个数分析
- 二分图最大匹配(匈牙利算法) UVA 670 The dog task
- java学习&复习 2015/07/16
- POJ 1276 Cash Machine