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
- 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;
- }