堆排序是一种树形选择排序的方法,其特点是:在排序过程中,将L[1...N]视为一颗完全二叉树的顺序存储结构,利用完全二叉树的双亲结点与孩子结点之间的内在关系,在当前无序区中选择关键字最大(最小)的元素。
堆分为大根堆和小根堆。
大根堆的定义:
根节点大于左右孩子结点,左右子树又是一个大根堆的完全二叉树为大根堆;
小跟队的定义:
根节点小于左右孩子结点,左右子树又是一个小根堆的完全二叉树为小根堆;
本文以大根堆为例子。
堆排序的核心就在于建堆和调整堆。
建堆:
void BuildMaxHeap(int *arr,int len) {
for (int i = len / 2; i >= 0; i--)
{
AdjustDown(arr,i,len);
}
}
调整堆:
void AdjustDown(int *arr,int k,int len)
{
int temp = arr[k];
for (int i = 2 * k+1; i <= len; i = 2*i+1)
{
if (i < len && arr[i] < arr[i + 1])
{
i++;
}
if (temp >= arr[i]) break;
else
{
arr[k] = arr[i];
k = i;
}
}
arr[k] = temp;
}
完整代码:
#include<iostream>
using namespace std;
void AdjustDown(int *arr,int k,int len)
{
int temp = arr[k];
for (int i = 2 * k+1; i <= len; i = 2*i+1)
{
if (i < len && arr[i] < arr[i + 1])
{
i++;
}
if (temp >= arr[i]) break;
else
{
arr[k] = arr[i];
k = i;
}
}
arr[k] = temp;
}
void BuildMaxHeap(int *arr,int len) {
for (int i = len / 2; i >= 0; i--)
{
AdjustDown(arr,i,len);
}
}
void HeapSort(int* arr, int len)
{
BuildMaxHeap(arr, len);
for (int i = len-1; i >= 0; i--)
{
swap(arr[i], arr[0]);
cout << arr[i] << " ";
AdjustDown(arr, 0, i - 1);
}
}
int main()
{
int arr[] = { 7,4,3,8,1 };
HeapSort(arr, 5);
return 0;
}
执行结果: