您的位置:首页 > 其它

堆排序(Heap Sortd)

2015-01-12 09:43 253 查看


1.堆的定义

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。)如最大化堆如下:


左图为其存储结构,右图为其逻辑结构。利用堆顶记录的关键字值最小(或最大)的性质,从当前待排序的记录中依次选取关键字最小(或最大)的记录,就可以实现对数据记录的排序,这种排序方法称为堆排序。

4.堆排序的实现

实现堆排序需要解决两个问题:    1.如何由一个无序序列建成一个堆?    2.如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?

先考虑第二个问题,一般在输出堆顶元素之后,视为将这个元素排除,然后用表中最后一个元素填补它的位置,自上向下进行调整:首先将堆顶元素和它的左右子树的根结点进行比较,把最小的元素交换到堆顶;然后顺着被破坏的路径一路调整下去,直至叶子结点,就得到新的堆。  我们称这个自堆顶至叶子的调整过程为“筛选”。  从无序序列建立堆的过程就是一个反复“筛选”的过程。

1.构造初始堆

初始化堆的时候是对所有的非叶子结点进行筛选。

最后一个非终端元素的下标是[n/2]向下取整,所以筛选只需要从第[n/2]向下取整个元素开始,从后往前进行调整。

  比如,给定一个数组,首先根据该数组元素构造一个完全二叉树。

  然后从最后一个非叶子结点开始,每次都是从父结点、左孩子、右孩子中进行比较交换,交换可能会引起孩子结点不满足堆的性质,所以每次交换之后需要重新对被交换的孩子结点进行调整。

2.进行堆排序

有了初始堆之后就可以进行排序了。  堆排序是一种选择排序。建立的初始堆为初始的无序区。  排序开始,首先输出堆顶元素(因为它是最值),将堆顶元素和最后一个元素交换,这样,第n个位置(即最后一个位置)作为有序区,前n-1个位置仍是无序区,对无序区进行调整,得到堆之后,再交换堆顶和最后一个元素,这样有序区长度变为2。。。  不断进行此操作,将剩下的元素重新调整为堆,然后输出堆顶元素到有序区。每次交换都导致无序区-1,有序区+1。不断重复此过程直到有序区长度增长为n-1,排序完成。

3.堆排序实例

首先,建立初始的堆结构如图:


然后,交换堆顶的元素和最后一个元素,此时最后一个位置作为有序区(有序区显示为黄色),然后进行其他无序区的堆调整,重新得到大顶堆后,交换堆顶和倒数第二个元素的位置……



重复此过程:


最后,有序区扩展完成即排序完成:



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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  堆排序