堆排序
C++实现的堆排序,分为三个函数实现:
- 堆调整函数:保持最大/最小堆
- 堆构建函数:利用堆调整函数创建一个最大/最小堆
- 堆排序函数:每次取堆顶元素交换至数组最后,并将size减一,然后调整堆顶保持最大/最小堆
堆调整函数:
//调整堆为数组a,需要调整的结点序号为i,堆大小为size
void HeapAdjust(int* a, int i, int size)
{
int left = 2 * i; //i结点的左孩子标号为2*i
int right = 2 * i + 1; //i结点的右孩子标号为2*i+1
int max = i; //保存这三个结点中值最大的标号
if (left <= size && a[left] > a[i])
max = left; //左孩子大于i结点
if (right <= size && a[right] > a[max])
max = right; //右孩子大于当前的max结点
if (max != i)
{
//当三个结点中最大的不是i时与i交换,保持最大堆
swap(a, max, i);
//交换后标号为max的结点可能已经不是最大堆,需递归继续调整max
HeapAdjust(a, max, size);
}
}
堆构建函数
void BuildHeap(int a[], int size)
{
//从树的非叶子结点开始到树顶端
for (int i = size / 2; i >= 1; i--)
{
HeapAdjust(a, i, size); //调整i号结点
}
}
堆排序函数
void HeapSort(int a[], int size)
{
BuildHeap(a, size); //首先构建一个堆
//循环到i=2,最后交换1号和2号结点
for (int i = size; i >= 2; i--)
{
swap(a, i, 1); //将堆顶元素与最后元素交换
size--;
HeapAdjust(a, 1, size); //调整堆顶元素
}
}
完整代码:
#include <iostream>
using namespace std;
void swap(int a[], int i, int j)
{
int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
void HeapAdjust(int* a, int i, int size)
{
int left = 2 * i;
int right = 2 * i + 1;
int max = i;
if (left <= size && a[left] > a[i])
max = left;
if (right <= size && a[right] > a[max])
max = right;
if (max != i)
{
swap(a, max, i);
HeapAdjust(a, max, size);
}
}
void BuildHeap(int a[], int size)
{
for (int i = size / 2; i >= 1; i--)
{
HeapAdjust(a, i, size);
}
}
void HeapSort(int a[], int size)
{
BuildHeap(a, size);
for (int i = size; i >= 2; i--)
{
swap(a, i, 1);
size--;
HeapAdjust(a, 1, size);
}
}
void print(int a[], int size)
{
for (int i = 1; i < size; i++)
cout << a[i] << " ";
cout << a[size] << endl;
}
int main(int argc, char** argv)
{
int a[7] = { 0, 4, 6, 1, 5, 3, 2 };
cout << "排序之前的序列为:" << endl;
print(a, 6);
HeapSort(a, 6);
cout << "排序之后的序列为:" << endl;
print(a, 6);
return 0;
}