堆排序相比于之前的排序难度可能较大一些,其实不是算法本身,而是对于堆的理解和代码编写感到陌生。
Ki <= K2i
Ki <= K2i+1
满足这个条件的堆称为小顶堆;
Ki >= K2i
Ki >= K2i+1
满足这个条件的堆称为大顶堆;
其实堆是一种更容易让人理解的图像表示,它的本质还是一维数组,只是下标的比较是i,2i,2i+1之间的比较。
堆排序就是先将初始序列排成大顶堆(小顶堆),然后取出堆顶元素,将剩下的元素再排列成大顶堆(小顶堆),这样就会得到一个有序的序列。
#include"../init.h"
//typedef Sqlist HeapType;
void heapAdjust(Sqlist *p, int s, int e);
void heapsort(Sqlist *p){
int i;
for(i=(*p).length/2; i>0; i--){
heapAdjust(p,i,(*p).length);
}
for(i=(*p).length; i>1; i--){
exchange(&(*p).r[1],&(*p).r[i]);
heapAdjust(p,1,i-1);
}
}
void heapAdjust(Sqlist *p, int s, int e){
//已知除p->r[s]之外,其余元素已满足堆条件
int j;
RedType rc = (*p).r[s];
for(j=2*s; j<=e; j*=2){
if(j<e && (*p).r[j].key < (*p).r[j+1].key )
j++;
if(rc.key >= (*p).r[j].key)
break;
(*p).r[s] = (*p).r[j];
s = j;
}
(*p).r[s] = rc;
}
int main(){
Sqlist L;
init(&L);
heapsort(&L);
show(L.r);
return 0;
}