堆排序

VonGang原创,如有错误,欢迎指正。转载请注明:http://www.cnblogs.com/vongang/

堆排序的涵盖很广,笔者也是初窥门径,写不了很高深的东西,这里就记录一些简单的用法。

小根堆:根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆,又称最小堆。

大根堆:根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆,又称最大堆。

(这里讨论的只是二叉堆)

建堆过程:


堆排序过程



堆排序动画演示:http://www.jcc.jx.cn/xinwen3/news/kj/flash/2004/0426/1297.htm

典型题目HUD_1280 : http://acm.hdu.edu.cn/showproblem.php?pid=1280

代码:

#include <iostream>
#include
<cstdio>
using namespace std;

const int N = 3007;

int num[N*(N-1)/2];
int t[N];

void heapadjust(int x, int y) //调整堆(大根堆)
{
int i, j, tmp;
i
= x;
j
= i << 1;
tmp
= num[x];
while(j <= y)
{
if(j < y && num[j] < num[j+1]) j++;
if(tmp < num[j])
{
num[i]
= num[j];
i
= j;
j
= i << 1;
}
else break;
}
num[i]
= tmp;
}

int main()
{
int n, m, i, j;
while(~scanf("%d%d", &n, &m))
{
int k = 1;
for(i = 1; i <= n; i++)
{
scanf(
"%d", t + i);
if(i == 1)
{num[
1] = t[1]; continue;}
for(j = 1; j < i; j++)
num[k
++] = t[i] + t[j];
}
int t = n*(n-1)/2;
for(i = t/2; i >= 1; i--) heapadjust(i, t);
m
--;
while(t-- && m--)
{
printf(
"%d ", num[1]);
num[
1] = num[t+1];
heapadjust(
1, t);
}
printf(
"%d\n", num[1]);
}
return 0;
}
posted @ 2011-08-17 16:33  AC_Von  阅读(553)  评论(0编辑  收藏  举报