以下C代码在clion上调试通过,编译器为clang.
根据算法导论伪码编写,说明见注释
#include <stdio.h>
void max_heapify(int *A, int i,int heap_size)//调整堆.让A[i]在最大堆中下降,使以i为根的子树成为最大堆
{
int l =2*i;//计算i的左子下标
int r =2*i + 1;//计算i的右子下标
int largest = -1;
int temp = 0;
if( (l<=heap_size) && (A[l]>A[i]) )//保证不越界的情况下,比较i与其左右子结点
largest = l; //并使largest指向三者中key最大的结点
else
largest = i;
if( (r<=heap_size) && (A[r]>A[largest]) )
largest = r;
if(largest!=i)//若largest不是i,即找到了新largest
{ //将A[i]与A[largest]互换
temp = A[i];
A[i] = A[largest];
A[largest] = temp;
max_heapify(A,largest,heap_size);//以新的largest为根,递归向下调整子树
}
}
void build_max_heap(int *A,int heap_size)//建大根堆
{
int i;
for(i = heap_size/2;i>=1;i--)//从heap_size/2开始调整堆,因为这是下标最大的非叶结点
max_heapify(A,i,heap_size);//调整以i为根的子树
}
void heapsort(int *A,int heap_size)//堆排序
{
build_max_heap(A,heap_size);
int temp = 0;
int i;
for(i=heap_size;i>=2;i--)
{
temp = A[1];
A[1] = A[i];
A[i] = temp;
heap_size--;
max_heapify(A,1,heap_size);
}
}
int main()
{
int A[11] = {-1,4,1,3,2,16,9,10,14,8,7};//由于算法从1开始操作,故A[0]置为-1,表示不使用
heapsort(A,10);
int i;
for( i = 1;i<11;i++)
printf("%d ",A[i]);
return 0;
}
每次将大根堆的根移出堆(放到最后一片叶节点),然后堆size-1,因此输出为升序:
1 2 3 4 7 8 9 10 14 16