《算法导论》笔记 第6章 6.4堆排序算法

【笔记】

反复将大根堆的根与最后一个结点交换,堆的大小减一,对根结点执行MAX_HEAPIFY维护堆的性质。

最终 A 数组按升序排列。

    void heapSort() {
        buildMaxHeap();
        for (int i=length;i>=2;i--) {
            swap(A[1],A[i]);
            heapSize--;
            maxHeapify(1);
        }
    }


【练习】

6.4-1 说明 HEAPSORT 在数组 A = <5,13,2,25,7,17,20,8,4> 上的操作过程。






A = <2,4,5,7,8,13,17,20,25>


6.4-2 讨论在使用如下循环不变式时,HEAPSORT的正确性:

在每次for循环的迭代开始时,

子数组A[1..i]是一个包含了A[1..n]中的i个最小元素的最大堆;

而子数组A[i+1..n]包含了已排序的A[1..n]中的n-i个最大元素。

初始化:在第一轮迭代之前,i = n,A[1..n]是包含前n个最小元素的最大堆;子数组A[n+1..n]中没有元素,即已排好序的0个最大元素。

保持:将A[1..i]个包含了A[1..n]中的最小i个元素中的最大元素移动到 A[i],由于 A[i]>=A[1..i-1],A[i]<=A[i+1..n],因此A[i..n]包含了已排序的A[1..n]中的n-i+1个最大元素。

对新的根结点执行MAX_HEAPIFY保持堆的性质,因此A[1..i-1]是一个包含了A[1..n]中的i-1个最小元素的最大堆。

for 循环中递减i,为下一次迭代重新建立了循环不变式。

终止:过程终止时,i=1。根据循环不变式,我们知道A[2..n]包含了已排序的n-1个最大元素。A[1]是A[1..n]中最小的元素。

因此A[1..n]是一个已排好序的数组。


6.4-3 对一个其所有n个元素已按递增序排列的数组A,堆排序的运行时间是多少?若A的元素成降序呢?

当A升序排列时:

执行BUILD_MAX_HEAP建堆,时间 O(n)。 循环调用MAX_HEAPIFY维护堆,时间 O(n)*O(logn),总复杂度O(nlogn)。

当A降序排列时,与升序排列相同。


6.4-4 证明:堆排序的最坏情况运行时间为Ω(nlogn)。

引用别人家的证明:


*6.4-5 证明:在所有元素都不相同时,堆排序的最佳运行时间是Ω(nlogn)。


原文地址:https://www.cnblogs.com/cyendra/p/3681630.html