堆排序(Heap Sortd)
2015-01-12 09:43
253 查看
n个元素的序列H={k1, k2 , …kn} ,满足:
情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆)
情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆)
其中i=1,2,…,n/2向下取整。
2.堆的性质
①堆是一棵采用顺序存储结构的完全二叉树, k1是根结点;②堆的根结点是关键字序列中的最小(或最大)值,分别称为小(或大)根堆;
③从根结点到每一叶子结点路径上的元素组成的序列都是按元素值(或关键字值)非递减(或非递增)的;
④堆中的任一子树也是堆。
3.堆的存储
一般用数组来表示堆,若根结点存在序号0处, i结点的父结点下标就为(i-1)/2。i结点的左右子结点下标分别为2*i+1和2*i+2。
(注:如果根结点是从1开始,则左右孩子结点分别是2i和2i+1。)如最大化堆如下:
![](http://pic002.cnblogs.com/images/2012/325852/2012113021383415.png)
左图为其存储结构,右图为其逻辑结构。利用堆顶记录的关键字值最小(或最大)的性质,从当前待排序的记录中依次选取关键字最小(或最大)的记录,就可以实现对数据记录的排序,这种排序方法称为堆排序。
4.堆排序的实现
实现堆排序需要解决两个问题: 1.如何由一个无序序列建成一个堆? 2.如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?先考虑第二个问题,一般在输出堆顶元素之后,视为将这个元素排除,然后用表中最后一个元素填补它的位置,自上向下进行调整:首先将堆顶元素和它的左右子树的根结点进行比较,把最小的元素交换到堆顶;然后顺着被破坏的路径一路调整下去,直至叶子结点,就得到新的堆。 我们称这个自堆顶至叶子的调整过程为“筛选”。 从无序序列建立堆的过程就是一个反复“筛选”的过程。
1.构造初始堆
初始化堆的时候是对所有的非叶子结点进行筛选。最后一个非终端元素的下标是[n/2]向下取整,所以筛选只需要从第[n/2]向下取整个元素开始,从后往前进行调整。
比如,给定一个数组,首先根据该数组元素构造一个完全二叉树。
然后从最后一个非叶子结点开始,每次都是从父结点、左孩子、右孩子中进行比较交换,交换可能会引起孩子结点不满足堆的性质,所以每次交换之后需要重新对被交换的孩子结点进行调整。
2.进行堆排序
有了初始堆之后就可以进行排序了。 堆排序是一种选择排序。建立的初始堆为初始的无序区。 排序开始,首先输出堆顶元素(因为它是最值),将堆顶元素和最后一个元素交换,这样,第n个位置(即最后一个位置)作为有序区,前n-1个位置仍是无序区,对无序区进行调整,得到堆之后,再交换堆顶和最后一个元素,这样有序区长度变为2。。。 不断进行此操作,将剩下的元素重新调整为堆,然后输出堆顶元素到有序区。每次交换都导致无序区-1,有序区+1。不断重复此过程直到有序区长度增长为n-1,排序完成。3.堆排序实例
首先,建立初始的堆结构如图:![](http://pic002.cnblogs.com/images/2012/325852/2012113021435914.png)
然后,交换堆顶的元素和最后一个元素,此时最后一个位置作为有序区(有序区显示为黄色),然后进行其他无序区的堆调整,重新得到大顶堆后,交换堆顶和倒数第二个元素的位置……
![](http://pic002.cnblogs.com/images/2012/325852/2012113021455372.png)
重复此过程:
![](http://pic002.cnblogs.com/images/2012/325852/2012113021474819.png)
最后,有序区扩展完成即排序完成:
![](http://pic002.cnblogs.com/images/2012/325852/2012113021482583.png)
4.实现代码
void Heap_Adjust(int array[],int start,int end) { int i; int temp; temp=array[start]; for(i=2*start+1;i<=end;i*=2) { if(i<end && array[i]<array[i+1]) { i++; } if(temp>=array[i]) break; array[start]=array[i]; start=i; } array[start]=temp; } void Heap_Sort(int array[],int n) { int i; int temp; for(i=n/2;i>=0;i--) { Heap_Adjust(array,i,n-1); } for(i=n-1;i>0;i--) { temp=array[0]; array[0]=array[i]; array[i]=temp; Heap_Adjust(array,0,i-1); } }
5.堆排序分析
堆排序的比较次数的数量级为: T(n)=O(n㏒2n);而附加空间就是交换时所用的临时空间,故空间复杂度为: S(n)=O(1) 。参考资料:http://www.cnblogs.com/mengdd/archive/2012/11/30/2796845.html
相关文章推荐
- 堆排序(heap_sort)
- 堆排序 HeapSort
- 排序——堆排序(Heap Sortd)
- 数据结构 - 堆排序(heap sort) 具体解释 及 代码(C++)
- 堆排序(HeapSort)
- php堆排序(heapsort)练习
- 堆排序(Heap Sort)
- 2011-03-04 CLRS Chapter6 Heapsort 堆排序 优先队列
- 堆排序(Heapsort)之Java实现
- 堆排序Heap Sort——浅显易懂+Java实现
- 堆排序Heap Sort——浅显易懂+Java实现
- PAT甲题题解1098. Insertion or Heap Sort (25)-(插入排序和堆排序)
- 堆排序(Heap Sort)算法学习
- Insertion or Heap Sort PAT甲级真题(堆排序)
- 【CLRS】《算法导论》读书笔记(一):堆排序(Heapsort)
- 堆排序(Heap Sort)
- 堆排序 heapSort
- 排序1+4:归并排序(MergeSort)和堆排序(HeapSort)
- 八大排序算法之四选择排序—堆排序(Heap Sort)
- 堆--堆排序--heap--heap_sort