堆排序
定义:
堆排序是指利用heap这种数据结构所设计的一种排序算法,是选择排序的一种。可以利用数组的特点快速定位指定索引的元素,是完全二叉树。
分类:
堆分为大堆和小堆,大堆要求每个节点的值均不大于其父节点的值,小堆要求每个节点的值均不小于其父节点的值。
性能:
堆排序是不稳定的排序算法。(排序的稳定性是指如果在排序的序列中,存在前后相同的两个元素的话,排序前和排序后他们的相对位置不发生变化)
时间复杂度:
O(N*logN)
空间复杂度:
O(1)
建堆:
从小到大排序,即建大堆,每次将最大的数换到堆底进行操作 从大到小排序,即建小堆
优点:
适合用于大量数据排序。
缺点:
建堆所需要的比较次数很多,所以堆排序不适合比较很少的数据。而且构建初始堆和反复建堆,调整堆这部分时间开销很大。并且堆排序只能用于给随机访问的数据排序,一般只能用于数组
动图展示:
PS:
动图建的为小堆,代码实现为大堆,大小堆过程均类似,只需要改动几个大于,小于关系。
代码实现:
#include <iostream>
#include <Windows.h>
#include <assert.h>
using namespace std;
void AdjustDown(int* arr, int len, int parent) //下调
{
int child = parent * 2 + 1; //左孩子
while (child < len)
{
if ((child + 1) < len && arr[child] < arr[child + 1])
{
++child;
}
if (arr[child] > arr[parent])
{
swap(arr[child], arr[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
//堆排序
void HeapSort(int* arr, int len)
{
assert(arr);
for (int i = (len - 2) / 2; i >= 0; --i)
{
AdjustDown(arr, len, i);
}
size_t end = len - 1;
while (end > 0)
{
swap(arr[0], arr[end]);
AdjustDown(arr, end, 0);
--end;
}
}
void Print(int* arr, int len) //打印
{
for (int i = 0; i < len; ++i)
{
cout << arr[i] << " ";
}
cout << endl;
}
#include "HeapSort.h"
void TestSelectSort()
{
int arr[] = { 58, 99, 66, 34, 21, 2, 0, 8, 7, 6, 5, 222222, 111, 888, 3 };
int len = sizeof(arr) / sizeof(arr[0]);
cout << "未排序数据:" << "";
Print(arr, len);
HeapSort(arr, len);
cout << "已排序数据:" << "";
Print(arr, len);
}
int main()
{
TestSelectSort();
system("pause");
return 0;
}