用比较简单的方法实现堆排序
来源:互联网 发布:网络企鹅使用方法 编辑:程序博客网 时间:2024/06/06 13:12
最近在学习算法导论的时候,对于堆排序这部分,在CSDN上找了一篇文章,感觉代码写的比较复杂,不是很有逻辑,因此把书好好的看了一篇,按书中的思想自己完成了堆排序的代码,看起来逻辑比较清晰一些。
分首先排序分为最大堆和最小堆,最大堆是指每个父节点的值都不小于它孩子节点的值,最小堆是指每个父节点的值都不大于它孩子节点的值,我们这里以最大堆为例进行讨论。PS:需要用到的几个小知识,编号为i的节点(树的节点都从1开始),左孩子为2i,右孩子为2i+1,父节点为i/2。
堆排序的核心步骤是如何保证每颗树满足最大堆的特性,比如现在A[LEFT],A[RIGHT]都是最大堆,但是他们2个的父节点A[I]不一定都比这2个孩子大,因此就需要调整,使这颗树成为最大堆。代码如下:
void max_heapify(int arrary[],int i,int m){if (arrary==NULL||i<=0)return ;if (i>m)return;int left,right,largest;left=2*i;right=2*i+1;if (left<=m&&arrary[left-1]>arrary[i-1]){largest=left;}elselargest=i;if (right<=m&&arrary[right-1]>arrary[largest-1]){largest=right;}if (largest!=i){int temp;temp=arrary[i-1];arrary[i-1]=arrary[largest-1];arrary[largest-1]=temp;max_heapify(arrary,largest,m);}}
传入的参数为1个数组,i为需要调整为最大堆的节点编号,m为数组元素的个数。通过比较i和他的左右子数的大小,来调整i为最大堆,此时调整了位置的largest节点可能违反了最大堆的性质,因此再调整largest这个节点为最大堆直至i下面的子树都变成最大堆。
另外一个步骤就是进行建堆,如何把数组和完全二叉树联系起来。代码如下:
void build_max_haep(int array[],int l){int m=l/2;for (int k=m;k!=0;--k){max_heapify(array,k,l);}}
一颗有l个节点的二叉树,从l/2+1开始都是叶子节点,因此从1到l/2都是有孩子的父节点,从l/2开始依次调整每颗树为最大堆,这样这步完成后,整个树就变成了最大堆。
通过上面的建堆,已经变成了最大堆,那么A[0]就是数组中最大的节点啦,现在要排序应该怎么办呢?
void heap_sort(int array[],int length){build_max_haep(array,length);for (int i=length;i!=1;--i){int temp;temp=array[0];array[0]=array[i-1];array[i-1]=temp;--length;max_heapify(array,1,length);}}
这个for循环,就是把A[0]和数组中最后1个元素交换,那么最大的值就到A[i-1]中去了,此时在把1到i-1的元素继续调整为最大堆,得到最大的值放到A[i-2]中,这样最后A[]数组就变成从小到的的数组了。
void main(){int a[]={8,2,4,7,1,14,9,10,3,16};heap_sort(a,sizeof(a)/sizeof(a[0]));for (size_t ix=0;ix!=sizeof(a)/sizeof(a[0]);++ix){cout << a[ix] <<endl;}}
下面是运行结果:
- 用比较简单的方法实现堆排序
- 堆排序中两种建堆方法的比较
- 简单选择排序与堆排序的比较
- 堆排序简单实现
- 堆排序 简单实现
- 堆排序的过程及简单实现
- 堆排序:插入方法建堆和普通方法建堆的比较
- 实现一个简单的最大二叉堆和堆排序
- 归并排序,堆排序,快排的简单实现
- 简单的排序---堆排序
- 用Javascript实现冒泡排序,二种方法的比较
- 常见比较排序算法的实现(归并排序、快速排序、堆排序、选择排序、插入排序、希尔排序)
- 堆排序 合并排序 快速排序 简单比较
- 快速排序、堆排序、归并排序简单比较
- 用堆实现堆排序
- 【堆/排序】堆排序的两种建堆方法
- c++实现简单的建堆、维护堆和堆排序
- 堆排序的实现
- 几个C#日期、时间验证的正则表达式
- 黑马程序员之IO流
- UVA - 12124 Assemble
- cocos2dx 移值到android平台问题总结
- ubuntu中运行程序libg2c.so.0 文件找不到 解决方法
- 用比较简单的方法实现堆排序
- 玩转PMan
- poj1002 487-3279 (简单字符串处理)
- iphone有关QQ和微信无法收到推送通知的终极解决方案
- JavaScript -- Input Select 操作, 级联菜单
- Adjacency Matrix of Graph(图的邻接矩阵)
- WinMain函数
- PIG安装配置及案例应用
- 速度与激情男主角车祸身亡