您的位置:首页 > 其它

堆排序(模板)

2011-04-12 20:08 204 查看
这两天看了下堆排序, 意思是理解了,不过还没找到用处。。。

先练练打字吧。。

堆排序(Heap Sort)只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。

堆的定义如下:n个元素的序列{k1,k2,k3.....kn}当且仅当满足以下关系时,称之为堆。

Ki <= K(2*i) && Ki <= K(2*i+1) 或者 Ki >= K(2*i) && Ki >= K(2*i+1) (i=1,2,...n/2)

若将此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右

孩子的结点的值。由此,若序列{k1,k2,...kn}是堆,则堆顶元素(或完全二叉树的根)必须为序列中n个元素的最小值(或最大值)。

若在输出堆顶的最小值之后,使得剩余n-1个元素的序列重又建成一个堆,则得到n个元素中的次小值。如此反复执行,便能得到一个有序序列,这个过程称之为堆排序。

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

(此处省略n个字,由于需要画图,此处不便写,见谅。。)

我们称自堆顶至叶子的调整过程为“筛选”。

从一个无序序列建堆的过程就是一个反复“筛选”的过程。若将此序列看成是一个完全二叉树,则最后一个非终端结点是第n/2个元素,由此“筛选”只需从第n/2

个元素开始。

贴上代码:

# include<stdio.h>
int a[1000005];
/*void HeapAdjust1(int s,int length)
{
int rc,j;
for(j=2*s;j<=length;j*=2)
{
if(j<length && a[j+1]>a[j]) j++;
if(a[j]<=a[s]) break;
rc=a[j];
a[j]=a[s];
a[s]=rc;
s=j;
}
}*/
void HeapAdjus2(int s,int length)
{
int rc,j;
rc=a[s];
for(j=2*s;j<=length;j*=2)
{
if(j<length && a[j+1]>a[j]) j++;
if(a[j]<=rc) break;
a[s]=a[j];
s=j;
}
a[s]=rc;
}
int main()
{
int i,n,temp;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=n/2;i>=1;i--)
/*HeapAdjust1(i,n);*/
HeapAdjust2(i,n);
for(i=n;i>=2;i--)
{
temp=a[1];
a[1]=a[i];
a[i]=temp;
HeapAdjust(1,i-1);
}
for(i=1;i<=n;i++)
printf("%4d",a[i]);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: