堆排序
今天的种树是尝试了一下C++写一个堆排序。
堆排序的介绍
首先了解一下堆排序算法。
https://www.cnblogs.com/chengxiao/p/6129630.html
这篇文章介绍的非常详细,关键是有图。
然后是比较堆排序和快排。也就是我们为什么要学习堆排序。
https://www.cnblogs.com/xiaochun126/p/5086037.html
这个表格表达的清楚明白。
总结一下关键点:
- 快排的空间复杂度随着n增大,而堆排序空间复杂度稳定
- 快排的最坏情况的时间复杂度比堆排序要大
- 虽然平均时间复杂度看起来相同,但其实快排效率更高,所以快排使用更广泛
- 两者都不稳定
- 重点来了!!堆排序可以实现在N个数中计算最大或最小的 k 个数,效率较高,而快排不行
嗯嗯,最后一点是我学习堆排序的原因特殊应用场景
C++实现代码
#include <iostream>
using namespace std;
int arrs[] = { 23, 476, 65, 12, 3, 925, 8, 98, 76, 345, 90, 21, 762, 75, 34, 123, 61 };
int length = sizeof(arrs) / sizeof(arrs[0]);
//如果一个节点的两个子树都是有序堆,那么只要把这个节点的值向下交换到合适的位置,将形成一个大的有序堆
void fun(int *arr, int p, int len)
{
int node = arr[p];
int child = p * 2 + 1; // 左孩子
while(child < len)
{
int rchild = child + 1; // 右孩子
if (rchild < len && arr[rchild] > arr[child])
child = rchild;
if (node < arr[child])
{
arr[p] = arr[child];
p = child;
child = 2 * p + 1;
}
else
break;
}
arr[p] = node;
}
int main()
{
//初始化一个有序小顶堆
for (int i = length / 2 - 1; i >= 0; i--)
{
fun(arrs, i, length);
}
//把顶点值换到末尾,堆长减一,继续构建有序堆
for(int i = length - 1; i >= 0; i--)
{
int a = arrs[0];
arrs[0] = arrs[i];
arrs[i] = a;
fun(arrs, 0, i);
}
for(int i = 0; i < length; i++)
cout << arrs[i] << endl;
return 0;
}
运行结果
加油!种树+1