您的位置:首页 > 其它

排序算法总结(三)

2017-04-20 21:40 134 查看

堆排序

1.堆

  堆实际上是一棵完全二叉树,其任何一非叶节点满足性质:
 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]或者Key[i]>=Key[2i+1]&&key>=key[2i+2],满足Key[i]>=Key[2i+1]&&key>=key[2i+2]称为大顶堆,满足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]称为小顶堆。大顶堆的堆顶的关键字肯定是所有关键字中最大的,小顶堆的堆顶的关键字是所有关键字中最小的。

2.堆排序的思想

    利用大顶堆(小顶堆)堆顶记录的是最大关键字(最小关键字)这一特性,使得每次从无序中选择最大记录(最小记录)变得简单,堆排序的时间复杂度和归并排序,快速排序一样都是O(nlogn)。
    其基本思想为(小顶堆):
    1)将初始待排序关键字序列(R0,R2....Rn-1)构建成小顶堆,此堆为初始的为数组,他是无序的;
    2)将堆顶元素R[0]与最后一个元素R[n-1]交换,此时得到新的无序区(R0,R2,......Rn-2)和新的有序区(Rn),且满足R[1,2...n-1]>=R

    3)由于交换后新的堆顶R[0]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[0]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
操作过程如下:
     1)初始化堆:将R[0..n-1]构造为堆;
     2)将当前无序区的堆顶元素R[0]同该区间的最后一个记录交换,同时将堆的长度做size--,然后将新的无序区调整为新的堆。
     3)不断的重复2的操作直到size=0停止;
列子如下: 给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。
如下面图,画的不好看;



    简而言之就是:数组写成二叉树形式----调整为小顶堆----首尾互换------调整为小顶堆------首尾互换------直到size=0;
代码如下:
    
//整理节点time:O(lgn)
template<class T>
void MinHeapify(T arry[], int size, int element)
{
int lchild = element * 2 + 1, rchild = lchild + 1;//左右孩子
while (rchild<size)      //子孩子均在范围内
{
if (arry[element] <= arry[lchild] && arry[element] <= arry[rchild])//如果比左右孩子都小,完成整理
{
return;
}
//不论是左右边哪边最小,都将最小的那个交换为子父节点

if (arry[lchild] <= arry[rchild]) //如果左边最小
{
swap(arry[element], arry[lchild]);//把左面的提到上面
element = lchild;                 //循环时整理子树
}
else                                  //否则右面最小
{
swap(arry[element], arry[rchild]);//同理
element = rchild;
}
lchild = element * 2 + 1;
rchild = lchild + 1;//重新计算子孩子位置
}
if (lchild<size&&arry[lchild]<arry[element])    //子父左孩子判断
{
swap(arry[lchild], arry[element]);
}
return;
}
//堆排序time:O(nlgn)
template<class T>
void HeapSort(T arry[], int size)
{
int i;
//从子树开始整理树,最后变为小顶堆
for (i = size - 1; i >= 0; i--)
{
MinHeapify(arry, size, i);
}
while (size>0)
{
swap(arry[size - 1], arry[0]);//将根(最小)与数组最末交换
size--;                       //树长度减小
MinHeapify(arry, size, 0);    //整理树重新变为小顶堆
}
return;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  堆排序 排序算法