您的位置:首页 > 其它

排序算法之堆排序

2014-04-27 21:09 120 查看
堆是一种数据结构,可以把堆看成一颗完全二叉树。这个二叉树满足:任何一个非叶结点的值都不大于(或不小于其左右孩子结点的值),若父结点大则为大顶堆,若父节点小则为小顶堆。

堆的定义知,根节点是的最是最大的(或最小的),因此将一个无序的序列调整为一个堆,就可以找出这个序列的最大(最小值)。

堆排序的执行过程如下:(大顶堆)

1) 从无序序列所确定的完全二叉树的第一个非叶子结点开始,从右到左,从下至上,对每个结点进行调整,最终将得到一个大顶堆。

对结点的调整方法:将当前结点(假设为a)的值与其孩子结点进行比较,如果存在大于a值的孩子结点,则从中选出一个最大的一个与a交换。当a来到下一层的时候重复上述过程,直到a的孩子结点的值都小于a的值为止。

2)将当前无序序列中第一元素,反映在树中是根结点(假设为a)与无序序列中最后一个元素交换,假设为b。a进入有序序列,到达最终位置。无序序列中的元素减少1个,有序序列中的元素增加一个,此时中有结点b可能不满足堆的定义对其进行调整。

3)重复2)的过程,知道无序序列中的元素剩下一个是排序结束。

大顶堆的代码如下:

#include<stdio.h>

void Shift(int r[],int low,int high)
{
int i=low,j=2*i;//r[j] is the LeftChild
int temp=r[i];
while(j<=high)
{
if(j<high && r[j]<r[j+1])
++j;
if(temp<r[j])
{
r[i]=r[j];
i=j;
j=2*i;
}
else
break;
}

r[i]=temp;
}

void BigHeapSort(int r[],int n)
{
int i,temp;
for(i=n/2;i>=1;--i)
Shift(r,i,n);//  Initial BigHeap
for(i=n;i>=2;--i)
{
temp=r[1];
r[1]=r[i];
r[i]=temp;
Shift(r,1,i-1);
}
}

void main()
{
int i;
int a[11]={0,4,3,2,1,0,7,6,5,8,9};//下标从1开始
BigHeapSort(a,10);
for(i=1;i<=10;++i)
printf("%d ",a[i]);
}


小顶堆代码如下:
#include<stdio.h>

void static Shift(int r[],int low,int high)
{
int i=low,j=2*i,temp=r[i];
while(j<=high)
{
if(j<high && r[j]>r[j+1])
++j;
if(temp>r[j])
{
r[i]=r[j];
i=j;
j=2*i;
}
else
break;
}
r[i]=temp;
}

void LittleHeapSort(int r[],int n)
{
int i;
int temp;
for(i=n/2;i>=1;--i)
Shift(r,i,n);
for(i=n;i>=2;--i)
{
temp=r[1];
r[1]=r[i];
r[i]=temp;
Shift(r,1,i-1);
}
}

void main(void)
{
int i;
int a[11]={0,2,1,3,5,4,8,7,6,9,0};
LittleHeapSort(a,10);
for(i=1;i<=10;++i)
printf("%d ",a[i]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: