本文共 1342 字,大约阅读时间需要 4 分钟。
堆排序算法:
思路: 先将序列构成一个大顶堆,然后将将第一个元素和剩余大顶堆的最后一个元素调换,然后将然后元素数再-1,再将剩下的调整为大顶堆,一直循环,具体思路见代码注释。注:堆排序的时间复杂度为O(nlogn),性能上远远好过于冒泡、简单选择、直接插入排序,但是由于记录的比较与交换是跳跃式的,因此堆排序是一种不稳定的排序方法。
代码实现:
//堆排序(排序后为从小到大)#include#include using namespace std; void HeapAjust(int (&a)[9], int s, int m){ int tmp, j; tmp = a[s];//记录此时的结点s for (j = 2 * s; j <= m; j *= 2){ //如果它不是根结点,即如果(j=2*s)<=m满足 if (j < m&&a[j] < a[j + 1]){ //如果它有右子树且右子树的值大,++j ++j; } if (tmp >= a[j]){ //如果刚开始的结点s的值比这个大,就不执行 break; } a[s] = a[j];//否则,就将结点s的值和结点j的值进行调换 s = j; } a[s] = tmp;}void HeapSort(int (&a)[9]){ //数组作为引用形参传入,使用在此修改对原数组也有效 int asize = sizeof(a) / sizeof(a[0]);//取数组的大小 int i; for (i = asize / 2-1; i >= 0; --i){ //先这个序列调整为大顶堆 HeapAjust(a, i, asize-2); } for (i = asize - 1; i > 0; --i){ swap(a[0], a[i]);//将第一个元素和剩余大顶堆的最后一个元素调换 HeapAjust(a, 0, i - 1);//将然后元素数再-1,然后再将剩下的调整为大顶堆 }}int main(){ int a[] = { 9, 1, 5, 8, 3, 7, 4, 6, 2 }; cout << "before sorted:" << endl; for (size_t i = 0; i < 9; ++i){ //输出 cout << a[i] << " "; } cout << endl; HeapSort(a); cout << "after sorted:" << endl; for (size_t i = 0; i < 9; ++i){ //输出 cout << a[i] << " "; } cout << endl; return 0;}
运行结果: