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;
}
下一篇:5.javase_循环语句