堆排序
原理
基本思想:将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根节点。将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),然后将剩余的 n-1 个子序列重新构造成一个堆,这样就会得到 n 个元素中的次大值。如此反复执行,就能得到一个有序序列。
可用动图描述为:
**
性能
**
时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|
O(nlogn) | O(1) | 非稳定性排序 |
大顶堆C++代码如下:
#include<iostream>
using namespace std;
//交换函数
void swap(int arr[], int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void HeapAdjust(int arr[], int i, int length)
{
//调整i位置的结点
//先保存当前结点的下标
int max = i;
//当前结点左右孩子结点的下标
int parent;
int lchild = 2 * i + 1;
int rchild = 2 * i + 2;
if (lchild < length && arr[lchild] > arr[max])
{
max = lchild;
}
if (rchild < length && arr[rchild] > arr[max])
{
max = rchild;
}
//若i处的值比其它左右孩子结点的值小,就将其和最大值进行交换
if (max != i)
{
swap(arr, i, max);
//递归
HeapAdjust(arr, max, length);
}
}
//堆排序
void HeapSort(int arr[], int length)
{
//初始化堆
//length / 2 - 1是二叉树中最后一个非叶子结点的序号
//把数组构成一个大顶堆
for (int i = length / 2 - 1; i >= 0; i--)
{
HeapAdjust(arr, i, length);
}
for (int i = length - 1; i >= 0; i--)
{
//将堆顶记录和当前未经排序子序列的最后一个记录交换
swap(arr, 0, i);
//重新调整为大顶堆
HeapAdjust(arr, 0, i );
}
}
int main ()
{
int arr[] = {9,8,6,7,5,3,4,1,2,0};
int length = sizeof(arr) / sizeof(arr[0]);
HeapSort(arr, length);
for (int i = 0; i < length; i++)
{
cout << arr[i] << " ";
}
return 0;
}
大顶堆测试结果:
小顶堆代码如下:
#include<iostream>
using namespace std;
void swap(int arr[], int i, int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void HeapAdjust(int arr[], int i, int length)
{
int min = i;
int lchild = 2 * i + 1;
int rchild = 2 * i + 2;
if (lchild < length && arr[lchild] < arr[min])
{
min = lchild;
}
if (rchild < length && arr[rchild] < arr[min])
{
min = rchild;
}
if (min != i)
{
swap(arr, min, i);
HeapAdjust(arr, min, length);
}
}
void HeapSort(int arr[], int length)
{
for (int i = length / 2 - 1; i >= 0; i--)
{
HeapAdjust(arr, i, length);
}
for (int i = length - 1; i >= 0; i--)
{
swap(arr, 0, i);
HeapAdjust(arr, 0, i );
}
}
int main ()
{
// int arr[] = {4, 1, 2, 3, 6, 7, 5, 9, 8};
int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
int length = sizeof(arr) / sizeof(arr[0]);
HeapSort(arr, length);
for (int i = 0; i < length; i++)
{
cout << arr[i] << " ";
}
return 0;
}
小顶堆测试结果如下: