排序之堆排序(Heap Sort)
2013-12-07 19:18
627 查看
堆的定义:
具有n个元素的序列{k1 , k2 , k3 ......kn},当且仅当满足条件:
此时序列成为堆;
若用数组存储堆,则堆可以看作完全二叉树,只不过其任一非叶节点满足上述性质,即:
Key[i] <= key[2i] && Key[i] <= Key[2i + 1](小顶堆) 或者Key[i] => Key[2i] && Key[i] => Key[2i + 1](大顶堆)
(1)所有非叶节点均不大于或者均不小于其左右子节点;
(2)所有节点的左子树或者右子树皆满足上述条件;
举例:
大顶堆逻辑结构;
堆一般用数组存储,一般节点i的父节点下标为(i - 1) / 2; 左孩子节点下标为(2*i + 1),右孩子节点下标为(2*i + 2);
堆排序思想:
利用大顶堆(小顶堆)堆顶记录的是最大(小)关键字这一特性,我们只需逐渐从无序序列中选择最大(小值);
其基本思想(大顶堆):
1)将初始待排关键字序列{K1 , K2 , K3 ,......Kn}构建为大顶堆,此时此堆为初始的无序区;
2)将堆顶元素K[1] 与 最后一个元素K
交换,此时形成新的无序区{K1 , K2 , K3 ,......Kn-1} 和新的有序区{Kn} , 并且数组满足K[1 , 2 , 3 .....n-1] <= K
;
3) 由于交换后新的堆顶K[1]可能违反大顶堆的性质,故需要对当前的无序序列{K1 , K2 , K3 ,......Kn-1}重新调整,然后再次将新的堆顶K[1] 与最后一个元素交换;
得到新的无序区{K1 , K2 , K3 ,......Kn-2} 和有序区{Kn-1 , Kn},重复上述操作,直至有序区的个数满足n-1;
堆排序操作重点:构建初始堆 和 调整交换后的堆;
其实构建初始堆也是一个调整的过程,只不过调整对象皆为非叶子节点;
下面将举例:
给定数组data[] = {23 , 14 , 5 , 34 , 56 , 89};
根据给定数组构建完全二叉树:
如上述(1)--(4),展现了如何初始构建大顶堆的;其中的步骤(4),在将(89 ,23)互相交换后,因为(23 > 5)子树根节点23,满足大顶堆性质故不再对子树进行调整;
即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。
再初始构建完毕后,进入调整排序操作:
将堆顶元素与堆末尾元素进行交换,
代码实现:
具有n个元素的序列{k1 , k2 , k3 ......kn},当且仅当满足条件:
此时序列成为堆;
若用数组存储堆,则堆可以看作完全二叉树,只不过其任一非叶节点满足上述性质,即:
Key[i] <= key[2i] && Key[i] <= Key[2i + 1](小顶堆) 或者Key[i] => Key[2i] && Key[i] => Key[2i + 1](大顶堆)
(1)所有非叶节点均不大于或者均不小于其左右子节点;
(2)所有节点的左子树或者右子树皆满足上述条件;
举例:
大顶堆逻辑结构;
堆一般用数组存储,一般节点i的父节点下标为(i - 1) / 2; 左孩子节点下标为(2*i + 1),右孩子节点下标为(2*i + 2);
堆排序思想:
利用大顶堆(小顶堆)堆顶记录的是最大(小)关键字这一特性,我们只需逐渐从无序序列中选择最大(小值);
其基本思想(大顶堆):
1)将初始待排关键字序列{K1 , K2 , K3 ,......Kn}构建为大顶堆,此时此堆为初始的无序区;
2)将堆顶元素K[1] 与 最后一个元素K
交换,此时形成新的无序区{K1 , K2 , K3 ,......Kn-1} 和新的有序区{Kn} , 并且数组满足K[1 , 2 , 3 .....n-1] <= K
;
3) 由于交换后新的堆顶K[1]可能违反大顶堆的性质,故需要对当前的无序序列{K1 , K2 , K3 ,......Kn-1}重新调整,然后再次将新的堆顶K[1] 与最后一个元素交换;
得到新的无序区{K1 , K2 , K3 ,......Kn-2} 和有序区{Kn-1 , Kn},重复上述操作,直至有序区的个数满足n-1;
堆排序操作重点:构建初始堆 和 调整交换后的堆;
其实构建初始堆也是一个调整的过程,只不过调整对象皆为非叶子节点;
下面将举例:
给定数组data[] = {23 , 14 , 5 , 34 , 56 , 89};
根据给定数组构建完全二叉树:
如上述(1)--(4),展现了如何初始构建大顶堆的;其中的步骤(4),在将(89 ,23)互相交换后,因为(23 > 5)子树根节点23,满足大顶堆性质故不再对子树进行调整;
即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。
再初始构建完毕后,进入调整排序操作:
将堆顶元素与堆末尾元素进行交换,
代码实现:
#include<iostream> using namespace std; //-------------------------------------------------------堆排序 -------------------------------------------------------------------------- void MaxHeapAdjust(int* data , int i , int Length); /* **data:被调整的数组data **dLength:数组长度 **函数功能:将数组data调整为排序数组 */ void heapSort(int* data , int dLength) { if(data == NULL || dLength <= 0) return; //初始构建大顶堆 for(int i = (dLength - 1) / 2; i >= 0; i--) MaxHeapAdjust(data , i , dLength); for(int i = (dLength - 1); i > 0; i--) { //交换首尾元素 swap(data[i] , data[0]); //去除最后元素,对剩余新的堆进行调整,以便满足大顶堆性质 MaxHeapAdjust(data , 0 , i - 1); } } /* ***int i :子树的根节点 ***int Length:子树的长度 ***函数功能:将data[i .....Length]调整为大顶堆 */ void MaxHeapAdjust(int* data , int i , int Length) { int temp = data[i]; //以节点i为根的子树,child指向左子节点 int child; for( child = 2*i ; child <= Length; child *= 2) { //若子节点值 < 右节点值,child指向右节点 if(child < Length && data[child] < data[child +1]) child++; if(temp >= data[child]) break; data[i] = data[child]; //此时i指向了较大的孩子节点 i = child; } data[i] = temp; } int main() { int data[] = {5 , 1 , 4, 3 }; int dLength = sizeof(data) / sizeof(int); cout<<"初始数组:"; for(int i = 0; i < dLength; i++) cout<<data[i]<<'\t'; cout<<'\n'; cout<<"排序数组:"; heapSort(data , dLength); for(int i = 0; i < dLength; i++) cout<<data[i]<<'\t'; cout<<endl; }
相关文章推荐
- 选择排序算法:堆排序-Heap Sort
- 【排序算法】 堆排序 heap sort(选择类排序)
- 排序——堆排序(HeapSort)
- 堆积排序-堆排序-heap sort
- 基本排序方法及分析(七):HeapSort 堆排序
- 排序——堆排序(Heap Sortd)
- 排序1+4:归并排序(MergeSort)和堆排序(HeapSort)
- Atitit 算法之道 attilax著 1. 第二部分(Part II) 排序与顺序统计(Sorting and Order Statistics) 1 2. 第六章 堆排序(Heapsort)
- 排序1+4:归并排序(MergeSort)和堆排序(HeapSort)
- 一天一排序之“堆排序(heapsort)”
- 选择排序之堆排序(HeapSort)
- 八大排序算法之四选择排序—堆排序(Heap Sort)
- PHP实现排序堆排序(Heap Sort)算法
- 算法珠玑--再看堆排序(Heap Sort)的实现
- 排序算法 之 堆排序(heapsort)
- 堆排序(Heap Sort)
- 堆排序(HeapSort)
- [Java--常见排序算法]--堆排序 (Heap Sort)
- Heap Sort(堆排序)
- 堆排序(Heap Sort)