堆排序
2015-07-08 20:25
253 查看
堆是一种完全二叉树,分为小根堆和大根堆。大根堆中任意节点的值都不大于其父节点的值。有些类似于二叉搜索树,都是要求父节点和子节点的值满足某种关系。
堆排序的基本思想是,先用所给数据建立大根堆,堆顶元素即为最大值,将其与最后一个元素交换,此时最后一个元素为最大值;再对最大值之前的元素进行调整,使其恢复为大根堆。再如此将次大值取出排列在最大值之前,循环往复,直到所有元素都排好序。
于是,排序的关键就是建堆和调整。如下HeapAjust函数实现调整树的功能,使其满足堆的性质。算法是:从一个指定节点开始,如果某个节点的值小于其子节点的值,就将其与较大的子节点交换,以使当前父节点与子节点满足堆的性质;然而,进行调整后,以被交换的子节点为根的子树可能又不满足堆的性质了,因此需要继续向下迭代遍历,直到当前节点满足堆的性质,就退出循环。
这是调整函数,想要建立堆,需要从最后一个非叶节点开始,自底向上调用此函数。堆排序时,每次取出堆中的最大元素后,要对剩下的元素进行调整,以维持堆的性质。直到所有节点都已取出,完成排序。
这是百度百科中调整函数、堆排序函数及测试代码:
堆排序的基本思想是,先用所给数据建立大根堆,堆顶元素即为最大值,将其与最后一个元素交换,此时最后一个元素为最大值;再对最大值之前的元素进行调整,使其恢复为大根堆。再如此将次大值取出排列在最大值之前,循环往复,直到所有元素都排好序。
于是,排序的关键就是建堆和调整。如下HeapAjust函数实现调整树的功能,使其满足堆的性质。算法是:从一个指定节点开始,如果某个节点的值小于其子节点的值,就将其与较大的子节点交换,以使当前父节点与子节点满足堆的性质;然而,进行调整后,以被交换的子节点为根的子树可能又不满足堆的性质了,因此需要继续向下迭代遍历,直到当前节点满足堆的性质,就退出循环。
这是调整函数,想要建立堆,需要从最后一个非叶节点开始,自底向上调用此函数。堆排序时,每次取出堆中的最大元素后,要对剩下的元素进行调整,以维持堆的性质。直到所有节点都已取出,完成排序。
这是百度百科中调整函数、堆排序函数及测试代码:
#include <stdio.h> //array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度 //本函数功能是:调整以第i个节点(即值为array[i]的节点)为根节点的树,使其成为大根堆 void HeapAdjust(int array[], int i, int nLength) { int nChild; int nTemp; for(; 2*i+1 < nLength; i=nChild) { //子结点的位置=2*(父结点位置)+1 nChild = 2*i+1; //得到子结点中较大的结点 if(nChild < nLength-1 && array[nChild+1] > array[nChild]) ++nChild; //如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点 if(array[i] < array[nChild]) { nTemp=array[i]; array[i]=array[nChild]; array[nChild]=nTemp; } else break; //否则退出循环 } } //堆排序算法 void HeapSort(int array[], int length) { int i, j; //建堆 //调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素 //length/2-1是最后一个非叶节点,此处"/"为整除 for(i=length/2-1; i>=0; --i) { HeapAdjust(array, i, length); } //从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素 for(i=length-1; i>0; --i) { //把第一个元素和当前的最后一个元素交换, //保证当前的最后一个位置的元素都是在现在的这个序列之中最大的 array[i] = array[0]^array[i]; array[0] = array[0]^array[i]; array[i] = array[0]^array[i]; //不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值 HeapAdjust(array,0,i); } } int main() { int i; int num[]={0,1,2,3,4,5,6,7,8,9}; HeapSort(num, sizeof(num)/sizeof(int)); for(i=0; i < sizeof(num)/sizeof(int); i++) { printf("%d ",num[i]); } printf("\n"); return 0; }
相关文章推荐
- Java解析HTML之HTMLParser使用与详解
- Count the Colors
- vim温馨提示
- Mongodb的范式化和反范式化
- IOS中OC的BLOCK问题
- 数据结构与算法-约瑟夫问题
- iOS学习9_事件分发&响应链
- iOS学习9_事件分发&响应链
- 移动端高清、多屏适配方案
- [转]LNMP环境下的Web常见问题排查(精品)
- 字符串相乘(算法)
- LeetCode Rotate Array
- 【独立开发者er Cocos2d-x实战 002】使用Cocos Studio创建帧动画
- ER-Studio使用外键为null设定方法
- linux centos使用xrdp远程界面登陆
- Python的dict数据结构
- linux centos使用xrdp远程界面登陆
- HtmlParser基础教程
- 在Mac下配置php开发环境:Apache+php+MySql
- 南阳oj 题目34 韩信点兵