升序最大堆 降序最小堆
visual C++ 下使用C语言实现堆排序
#include <stdio.h>
#define MAXSIZE 10
typedef int KeyType;
typedef struct {
KeyType key; // 关键字项
// int otherinfo; // 其它数据项
} RcdType;
typedef struct {
RcdType r[MAXSIZE+1]; // r[0]闲置
int length; // 顺序表长度
} SqList;
typedef SqList HeapType;
void HeapAdjust (RcdType R[], int s, int m);
void HeapSort ( HeapType &H ) {
// 对顺序表 H 进行堆排序
int i;
for ( i=H.length/2; i>0; --i )
HeapAdjust ( H.r, i, H.length ); // 建大顶堆
for ( i=H.length; i>1; --i ) {
RcdType temp;
temp=H.r[1];
H.r[1]=H.r[i];
H.r[i]=temp;
// H.r[1]←→H.r[i];
// 将堆顶记录和当前未经排序子序列
// H.r[1..i]中最后一个记录相互交换
HeapAdjust(H.r, 1, i-1); // 对 H.r[1] 进行筛选
}
}
void HeapAdjust (RcdType R[], int s, int m)
{ // 已知 R[s..m]中记录的关键字除 R[s] 之外均
// 满足堆的特征,本函数自上而下调整 R[s] 的
// 关键字,使 R[s..m] 也成为一个大顶堆
RcdType rc;
rc = R[s]; // 暂存 R[s]
int j;
for ( j=2*s; j<=m; j*=2 ) { // j 初值指向左孩子
// 自上而下的筛选过程;
if ( j<m && R[j].key<R[j+1].key ) ++j;
// 左/右“子树根”之间先进行相互比较
// 令 j 指示关键字较大记录的位置
if ( rc.key >= R[j].key ) break;
// 再作“根”和“子树根”之间的比较,
// 若“>=”成立,则说明已找到 rc 的插
// 入位置 s ,不需要继续往下调整
R[s] = R[j]; s = j;
// 否则记录上移,尚需继续往下调整
}
R[s] = rc; // 将调整前的堆顶记录插入到 s 位置
} // HeapAdjust
void main()
{
HeapType L={{0,21,34,12,6,78,45,10,20,70,30},10};
HeapSort(L);
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i]);
}