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
posted @ 2018-11-24 19:14  赫凯  阅读(41)  评论(0)    收藏  举报