本文以最大堆为例。
首先是一个交换对象值的函数
void swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
// 对的下移操作:加入一个元素破坏了最大堆的性质:它太小了,于是我们需要把它向下移动到合适的位置
void shift_down(int H[], int n, int i)
{
while (i * 2 <= n)
{
i = i * 2;
if (i + 1 <= n && H[i + 1] > H[i])
{
i = i + 1;
}
if (H[i / 2] < H[i])
{
swap(H[i / 2], H[i]);
}
else
{
break;
}
}
}
// 堆的建立:把叶子节点以上的所有节点(即前一半节点,都下移到合适的位置)
void make_heap(int H[], int n)
{
H[0] = H[n];
int i;
for (i = n / 2; i >= 1; i--)
{
shift_down(H, n, i);
}
}
// 堆排序:把原来的数组(n个元素)建立成最大堆后,那么第一个元素肯定是最大元素,那么把第一个元素和最后一个元素互换,最大元素就是最后一个元素了,把堆的大小减一(只考虑前n-1个元素),把换上去的比较小的元素下移到合适的位置,那么前n-1个元素又组成了一个最大堆,重复以上的过程即可
void heap_sort(int H[], int n)
{
int i;
make_heap(H, n);
for (i = n; i > 1; i--)
{
swap(H[1], H[i]);
shift_down(H, i - 1, 1);
}
}
以上的每个函数除了make_heap外,都可以写成递归的形式。