小顶堆排序
/*
建堆的时间复杂度
STL中的优先队列
下标为i的节点的父节点的下标为 (i-1)/2
下标为j的节点的左子节点的下标为 j*2 + 1
下标为j的节点的右子节点的下标为 j*2 + 2
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
*/
#include <iostream>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;
int k = 0;
// 调整堆
int ModifyHeap(int array[], int Index, int Num)
{
for (;;) // 汇编指令少
{
int nMaxValueIndex = Index;
//下标为j的节点的左子节点的下标为 j * 2 + 1
//下标为j的节点的右子节点的下标为 j * 2 + 2
int LeftNode = (Index << 1) + 1; // 移位比乘法速度快Index * 2+ 1【相同条数指令的情况下,只有千亿级运算才能看出来】;
int RightNode = (Index << 1) + 2; // 移位比乘法速度快Index * 2+ 2;
// 小顶堆,找最小节点
if (LeftNode < Num && array[nMaxValueIndex] > array[LeftNode])
{
nMaxValueIndex = LeftNode;
}
if (RightNode < Num && array[nMaxValueIndex] > array[RightNode])
{
nMaxValueIndex = RightNode;
}
if (nMaxValueIndex != Index)
{
swap(array[nMaxValueIndex], array[Index]);
Index = nMaxValueIndex;
continue;
}
k++;
break;
}
return 0;
}
// 创建最小堆
int CreateMinHeap(int array[], int Num)
{
int LastIndex = Num - 1;
// 下标为i的节点的父节点的下标为(i - 1) / 2
for (int i = (LastIndex - 1) / 2; i >= 0; i--)
{
ModifyHeap(array, i, Num);
k++;
}
return 0;
}
// 排序
int SortMinHeap(int array[], int Num)
{
for (int i = Num - 1; i >= 0; i--)
{
swap(array[i], array[0]);
ModifyHeap(array, 0, i);
k++;
}
return 0;
}
int main()
{
default_random_engine e(static_cast<int>(time(0))); // 稍微随机些的种子
const int len = 32768; /* 数组长度 */
int a[len] = {0};
for (int i = 0; i < len; i++)
{
a[i] = e() & 0x7FFFFFFF;
}
CreateMinHeap(a, len);
SortMinHeap(a, len);
for (int i = len - 1; i >= 0; i--)
{
printf("%d\n", a[i]);
}
printf("\n...................................................................................");
// 检查正确性
for (int i = 0; i < len-1; i++)
{
if (a[i] < a[i+1])
{
printf("错误\n");
}
}
printf("\n...................................................................................");
printf("堆调整执行次数:k = %d\n", k);
while (true)
{
getchar();
}
return 0;
}