为什么会有堆排序?
堆排序是一种选择排序,最常见的就是简单选择排序。
void SelectSort(SqList&L){
for(i=1;i<L.length;++i){
j=SelectMinKey(L,i);
if(i!=j)
L.r[i]<->L.r[j];
}
简单选择排序的主要操作是进行关键字之间的比较,因此改进简单选择排序应从减少“比较”出发考虑。于是有了锦标赛式的排序即树形选择排序,有效利用比较信息。
但树形选择排序的方法有辅助存储空间较多,和“最大值”进行多余的比较的缺点,为了弥补,J.willioms在1964年提出了另一种形式的选择排序——堆排序。
堆排序(Heap Sort)
堆排序只需要一个记录大小的辅助空间,每个待排序的记录仅占有一个存储空间。
堆定义如下:
n个元素的序列{k1,k2,.....,kn}当且仅当满足下列关系时,称为堆
1 ki<=k2i 2 ki>=k2i
ki<=k2i+1 ki>=k2i+1
void Heap_Adjust(HeapType*H, int s, int m)
{
//已知H.r[s,,,m]中的记录的关键字除H.r[s]外均满足堆定义,本函数调整H.r[s]
//的关键字(即priority),使H.r[s,,,m]成为大根堆(对其中记录而言)
course rc = H->r[s];
int j = 0;
for (j = 2 * s; j <= m; j *= 2){
//沿key较大的孩子结点向下筛选
if (j < m &<(H->r[j].priority, H->r[j + 1].priority))//查找最大孩子
++j;
if (!LT(rc.priority, H->r[j].priority))//如果左右孩子比此节点小,退出
break;
H->r[s] = H->r[j];
s = j;//s为保留rc应该出现的位置
}
H->r[s] = rc;
}
void Heap_Sort(HeapType*H)
{
int i = 0;
for (i = H->length / 2; i > 0; --i)//将无序序列初始化为大根堆
Heap_Adjust(H, i, H->length);
for (i = H->length; i > 1; i--)
{
course r3;
r3 = H->r[1];
H->r[1] = H->r[i];
H->r[i] = r3;//交换会写错
Heap_Adjust(H, 1, i - 1);
}
}