算法总结系列之一:堆排序(Heap Sort)
2008-06-19 14:41
513 查看
在软件设计相关领域,"堆(Heap)"的概念主要涉及到两个方面:
一种数据结构,逻辑上是一颗完全二叉树,存储上是一个数组对象(二叉堆).
垃圾收集存储区,是软件系统可以编程的内存区域.
本文所说的堆,指的是前者.另外,这篇文章中堆中元素的值,均以整型为例.
堆排序的时间复杂度是O(nlgN),与快速排序达到相同的时间复杂度.但是在实际应用中,我们往往采用快速排序而不是堆排序.这是因为快速排序的一个好的实现,往往比堆排序具有更好的表现.堆排序的主要用途,是在形成和处理优先级队列方面.另外,如果计算要求是类优先级队列(比如,只要返回最大或者最小元素,只有有限的插入要求等),堆同样是很适合的数据结构.
基础知识
堆一般用数组表示,比如数组A.数组的长度Length(A),堆在数组中的元素个数HeapSize(A).一般说来,HeapSize(A)<=Length(A),因为数组A当中可能有一些元素不在堆中.
假设节点I是数组A中下标为i的节点.
Parent(i):returnFloor(i/2);//I的父节点下标.Floor(i)表示比i小的最大整数.
Left(i):return2*i;//I的左子节点
Right(i):return2*i+1;//I的右子节点
含有n个元素的堆A的高度是:Floor(lgn)
堆的基本操作
一种数据结构,逻辑上是一颗完全二叉树,存储上是一个数组对象(二叉堆).
垃圾收集存储区,是软件系统可以编程的内存区域.
本文所说的堆,指的是前者.另外,这篇文章中堆中元素的值,均以整型为例.
堆排序的时间复杂度是O(nlgN),与快速排序达到相同的时间复杂度.但是在实际应用中,我们往往采用快速排序而不是堆排序.这是因为快速排序的一个好的实现,往往比堆排序具有更好的表现.堆排序的主要用途,是在形成和处理优先级队列方面.另外,如果计算要求是类优先级队列(比如,只要返回最大或者最小元素,只有有限的插入要求等),堆同样是很适合的数据结构.
基础知识
堆一般用数组表示,比如数组A.数组的长度Length(A),堆在数组中的元素个数HeapSize(A).一般说来,HeapSize(A)<=Length(A),因为数组A当中可能有一些元素不在堆中.
假设节点I是数组A中下标为i的节点.
Parent(i):returnFloor(i/2);//I的父节点下标.Floor(i)表示比i小的最大整数.
Left(i):return2*i;//I的左子节点
Right(i):return2*i+1;//I的右子节点
含有n个元素的堆A的高度是:Floor(lgn)
堆的基本操作
MaxHeapify(A,i):
保持堆的性质.假设数组A和下标i,假定以Left(i)和Right(i)为根结点的左右两棵子树都已经是最大堆,节点i的值可能小于其子节点.调整节点i的位置.
算法的C#实现:
publicvoidMaxHeapify(int[]A,intheapSize,inti) { intleft=2*i; intright=2*i+1; intlarger=i; //comparewithleftchild if(left<=heapSize&&A[left]>A[i]) { larger=left; } //comparelargernodewithrightchild if(right<=heapSize&&A[right]>A[i]) { larger=right; } //exchangeiwiththelargerchild if(larger!=i) { inttmp=A[i]; A[i]=A[larger]; A[larger]=tmp; MaxHeapfy(A,heapSize,larger); } }
时间复杂度与树的高度成正比,为O(lgn).
BuildMaxHeap(A):
从一个给定的数组建立最大堆.子数组A[floor(n/2)+1.......n]中的元素都是树的叶节点(完全二叉树的基本性质).从索引ceiling(n/2)开始一直到1,对每一个元素都执行MaxHeapify,最终得到一个最大堆.
算法的C#实现:
publicvoidBuildMaxHeap(int[]A) { intheapSize=A.Length; for(inti=Math.Ceiling(heapSize/2);i>=1;i--) { MaxHeapify(A,heapSize,i); } }
时间复杂度依赖于MaxHeapifyO(h)(h-树的高度),BuildMaxHeap(A)的时间复杂度是O(n).
堆排序HeapSort(A):
堆排序算法的基本思想是,将数组A创建为一个最大堆,然后交换堆的根(最大元素)和最后一个叶节点x,将x从堆中去掉形成新的堆A1,然后重复以上动作,直到堆中只有一个节点.
算法的C#实现:
publicvoidHeapSort(int[]A)
{
BuildMaxHeap(A);
intHeapSize=A.Length;
for(inti=HeapSize;i>1;i--)
{
//assumethetypeofAisint[]forexample
inttmp=A[1];
A[1]=A[i];
A[i]=A[1];
HeapSize-=1; //cutoffthesortednode.
MaxHeapify(A,HeapSize,1);//sorttheA1toamaxheap
} }
堆排序的时间复杂度是O(nlgn).
优先级队列算法-增加某元素的值(优先级):HeapIncreaseKey(A,i,key)
增加某一个元素的优先级后(元素的值),该元素应该向上移动,才能保持堆的性质.
算法的C#实现:
publicvoidHeapIncreaseKey(int[]A,intindex,intkey)
{
if(key<=A[index])
return;
A[index]=key;
while(index>1&&A[Parent(index)]<A[index]]
{
//promptchildnode
inttmp=A[index]:
A[index]=A[Parent(index)];
A[Parent(index)]=tmp;
index=Parent(index);
}
}
时间复杂度:O(lgn)
优先级队列算法-插入一个元素:Insert(S,x)将x元素插入到优先级队列S中.
主要思路是,将堆的最后一个叶节点之后,扩展一个为无穷小的新叶节点,然后增大它的值为x的值
算法的C#实现是:
publicvoidHeapInsert(int[]A,intkey)
{
A.Length+=1;
A[A.Length]=int.MinValue;
HeapIncreasekey(A,A.Length,key);
}
时间复杂度O(lgn)
相关文章推荐
- (转)算法总结系列之一:堆排序(Heap Sort)
- 算法总结系列之一:堆排序(Heap Sort)
- Atitit 算法之道 attilax著 1. 第二部分(Part II) 排序与顺序统计(Sorting and Order Statistics) 1 2. 第六章 堆排序(Heapsort)
- 算法:堆排序(Heap Sort)
- HeapSort——堆排序实现(算法类)
- 算法总结系列之六: 桶排序(Bucket Sort)
- 算法学习 - 堆排序 ( HeapSort ) C++实现
- PHP实现排序堆排序(Heap Sort)算法
- Java堆排序(HeapSort)算法实现
- 堆排序(Heap Sort)算法的实现
- 算法分析之——heap-sort堆排序
- 算法总结系列之六: 桶排序(Bucket Sort)
- 算法总结系列之五: 基数排序(Radix Sort)
- 排序算法系列:堆排序(heapsort)(C语言)
- 排序算法总结之堆排序 Heap Sort
- 小小c#算法题 - 7 - 堆排序 (Heap Sort)
- 算法----堆排序(heap sort)
- 【算法导论学习-013】堆排序(Heapsort)
- c++堆排序实现(heapsort) (算法导论)
- algorithm: heap sort in python 算法导论 堆排序