C 堆排序
堆排序的关键在于构建初始堆,对初始序列建堆,就是一个反复筛选的过程。n个结点的完全二叉树,最后一个结点是第[n/2]个结点的孩子。对于[n/2]个结点为根的子树筛选,使该子树成为堆。之后向前一次对依次对各结点([n/2]-1~1)为根的子树进行筛选,看该结点值是否大于起左右子结点的值,若不是,将左右子结点的值与之交换,交换后可能破坏下一级的堆,于是继续采用上述方法构造下一级的堆,直到以该结点为根的子树构成堆为止。反复利用上述调整堆的方法建堆,直到根结点。
输出根结点后,通常将堆低元素送入堆顶,此时根结点已不满足大顶堆的性质,堆被破坏,将堆顶元素向下调整使其继续保持大顶堆的性质,再输出顶堆元素。如此重复,直到堆中仅剩下一个元素位置
借助的完全二叉树的结构,快速知道谁是最大的,并且把最大的调走后,又能快速知道剩下的里面哪个是最大的,有丶东西。
//向下调整
void AdjustDown(int a[], int k, int n){
//将元素k向下调整
int i;
//因为是二叉树结构,在0下标还是不放东西了,这样的话可以明确对应根结点和子结点关系
A[0] = a[k];
//沿着key较大的子结点向下筛选
for (i = 2*k; i <= n; i *= 2) {
//取key较大的子结点的下标
if(i < n && a[i] < a[i+1]){
i++;
}
if(a[0] >= a[i]) break;
else {
a[k] = a[i]; //将a[i]调整到双亲结点上
k = i; //修改k值,以便继续向下筛选
}
}
a[k] = a[0]; //被筛选的值放入最终的位置
}
void BuildMaxHeap(int a[], int n){
int i; //反复调整堆
for (i = n/2; i > 0; i--) {
AdjustDown(a, i, n);
}
}
void HeapSort(int a[], int n){
BuildMaxHeap(a, n); //先建立堆
int i, temp;
temp = a[1];
a[1] = a[i];
a[i] = temp;
AdjustDown(a, 1, i-1);
}
}
每次都是大顶堆结构,取出来和最后一个交换再调整
9857416023
8756413029
7653412089
6543012789
5423016789
4321056789
3201456789
2103456789
1023456789
0123456789
0123456789
本文来自博客园,作者:赫凯,转载请注明原文链接:https://www.cnblogs.com/heKaiii/p/15491239.html