Problem Description
堆排序是一种利用堆结构进行排序的方法,它只需要一个记录大小的辅助空间,每个待排序的记录仅需要占用一个存储空间。
首先建立小根堆或大根堆,然后通过利用堆的性质即堆顶的元素是最小或最大值,从而依次得出每一个元素的位置。
堆排序的算法可以描述如下:
在本题中,读入一串整数,将其使用以上描述的堆排序的方法从小到大排序,并输出。
Input Description
输入的第一行包含1个正整数n,表示共有n个整数需要参与排序。其中n不超过100000。
第二行包含n个用空格隔开的正整数,表示n个需要排序的整数。
Output Description
只有1行,包含n个整数,表示从小到大排序完毕的所有整数。
请在每个整数后输出一个空格,并请注意行尾输出换行。
Sample Input
10
2 8 4 6 1 10 7 3 5 9
Sample Output
1 2 3 4 5 6 7 8 9 10
Hint
在本题中,需要按照题目描述中的算法完成堆排序的算法。
堆排序对于元素数较多的情况是非常有效的。通过对算法的分析,不难发现在建立含有n个元素的堆时,总共进行的关键字比较次数不会超过4n,且n个节点的堆深度是log2n数量级的。因此,堆排序在最坏情况下的时间复杂度是O(nlog2n),相对于快速排序,堆排序具有同样的时间复杂度级别,但是其不会退化。堆排序较快速排序的劣势是其常数相对较大。
我的想法:
我的代码:
#include <iostream>
using namespace std;
typedef struct HeapLine
{
int *str;
int length;
}HeapLine;
void CreateLine(HeapLine &H, int n)
{
H.str = new int[n + 1];
H.length = n;
for (int i = 1; i <= H.length; i++)
{
cin >> H.str[i];
}
}
void DeleteLine(HeapLine &H)
{
delete []H.str;
H.length = 0;
}
void HeapAdjust(HeapLine &H, int s, int m)
{
int j;
int rc;
rc = H.str[s];
for (j = 2 * s; j <= m; j *= 2)
{
if (j < m && H.str[j] < H.str[j + 1])
++j;
if (rc > H.str[j])
break;
H.str[s] = H.str[j];
s = j;
}
H.str[s] = rc;//插入
}
void HeapSort(HeapLine &H)
{
int i;
int temp;
for (i = H.length / 2; i > 0; --i)
{
HeapAdjust(H, i, H.length);
}
for (i = H.length; i > 1; --i)
{
temp = H.str[i];
H.str[i] = H.str[1];
H.str[1] = temp;
HeapAdjust(H, 1, i - 1);
}
}
void Print(HeapLine &H)
{
for (int i = 1; i <= H.length; i++)
{
printf("%d ", H.str[i]);
/*if (i == 1)
{
printf("%d", H.str[i]);
}
else
{
printf(" %d", H.str[i]);
}*/
}
printf("\n");
}
int main()
{
int n;
HeapLine H;
while (scanf("%d", &n) != EOF)
{
CreateLine(H, n);
HeapSort(H);
Print(H);
DeleteLine(H);
}
return 0;
}