排序七之堆排序
2016-02-03 17:36
363 查看
Heap Sort
一种基于选择排序思想,利用堆结构和二叉树的一些性质来完成数据排序的排序算法。
堆排序的关键是构造堆结构,准确而言,堆结构即是一个完全二叉树,树中的每一个节点对应原始数据的一个记录。每个节点应满足以下条件:
1)从小到大排序:要求非叶结点的数据要大于或等于其左、右子节点的数据。
2)从大到小排序:要求非叶节点的数据要小于或等于其左、右子节点的数据。
一个完整的堆排序需要反复经过两个步骤:构造堆结构和堆排序的输出。
构造堆结构过程:
对于一个非叶结点Ai,这里假定Ai的左子树与右子树已经进行了筛运算,即已构成堆结构;
1:比较Ai的左子树与右子树的最大值,将最大值放在Aj中。
2:将Ai的数据与Aj的数据进行比较,如果Ai大于Aj表示以Ai为根的子树已构成堆结构,便可以终止运算。
3:如果Ai小于Aj,则将Ai与Aj互换位置。
4:经过第三步后,可能会破坏以Ai为根的堆,因为此时Ai的值为原来的Aj。下面以Aj为根重复前面的步骤,直到满足堆结构的定义,即父节点大于子节点。这样一Aj为根的子树就被调整为一个堆结构。
堆排序的输出过程:
1:将堆结构的根节点放到数组的最后。
2:除最后一个节点外的其他节点重新执行前面的构造堆过程。
一种基于选择排序思想,利用堆结构和二叉树的一些性质来完成数据排序的排序算法。
堆排序的关键是构造堆结构,准确而言,堆结构即是一个完全二叉树,树中的每一个节点对应原始数据的一个记录。每个节点应满足以下条件:
1)从小到大排序:要求非叶结点的数据要大于或等于其左、右子节点的数据。
2)从大到小排序:要求非叶节点的数据要小于或等于其左、右子节点的数据。
一个完整的堆排序需要反复经过两个步骤:构造堆结构和堆排序的输出。
构造堆结构过程:
对于一个非叶结点Ai,这里假定Ai的左子树与右子树已经进行了筛运算,即已构成堆结构;
1:比较Ai的左子树与右子树的最大值,将最大值放在Aj中。
2:将Ai的数据与Aj的数据进行比较,如果Ai大于Aj表示以Ai为根的子树已构成堆结构,便可以终止运算。
3:如果Ai小于Aj,则将Ai与Aj互换位置。
4:经过第三步后,可能会破坏以Ai为根的堆,因为此时Ai的值为原来的Aj。下面以Aj为根重复前面的步骤,直到满足堆结构的定义,即父节点大于子节点。这样一Aj为根的子树就被调整为一个堆结构。
堆排序的输出过程:
1:将堆结构的根节点放到数组的最后。
2:除最后一个节点外的其他节点重新执行前面的构造堆过程。
#include<stdio.h> #include<stdlib.h> #include<time.h> #define SIZE 10 void HeapSort(int *a,int n) { int i,j,h,k; int t; for(i=n/2-1;i>=0;i--) { while(2*i+1<n) { j=2*i+1; if((j+1)<n) { if(a[j]<a[j+1]) j++; } if(a[i]<a[j]) { t=a[i]; a[i]=a[j]; a[j]=t; i=j; } else{break;} } } for(i=n-1;i>0;i--) { t=a[0]; a[0]=a[i]; a[i]=t; k=0; while(2*k+1<i) { j=2*k+1; if((j+1)<i) { if(a[j]<a[j+1]) j++; } if(a[k]<a[j]) { t=a[k]; a[k]=a[j]; a[j]=t; k=j; } else{break;} } } } int main() { int i; int shuzu[SIZE]; srand(time(NULL)); for(i=0;i<SIZE;i++) shuzu[i]=rand()/1000+100; printf("排序后的数组为:\n"); for(i=0;i<SIZE;i++) printf("%d ",shuzu[i]); printf("\n"); HeapSort(shuzu,SIZE); printf("排序后的数组为:\n"); for(i=0;i<SIZE;i++) printf("%d ",shuzu[i]); printf("\n"); return 0; }
相关文章推荐
- Android酷炫实用的开源框架(UI框架)
- ssh-key Permission denied (publickey)
- 从Spark Streaming 收集应用程序日志到Flume agent的配置方法
- js 关闭窗口时判断表单数据是否改变
- How to use user’s location in your app?
- HttpClient设置代理,超时,以及得到cookies
- 第一个Storm的程序例子
- mysql delete数据时报Error Code 1175
- [android]如何使LinearLayout布局从右向左水平排列,而不是从左向右排列
- influx学习
- How to use cocoa pod in your iOS project
- redis 3.0的集群部署
- Linux命令:mv
- ActiveMQ
- MVC
- html5 audio总结
- (11)UI布局和分辨率适配
- druid
- KVM虚拟化笔记(五)------kvm虚拟机控制台登录配置
- android 开发之路的起点