《算法导论》笔记 第6章 6.2保持堆的性质

【笔记】

当 MAX_HEAPIFY(A, i) 被调用时,我们假定LEFT(i)、RIGHT(i)为根的两棵二叉树都是最大堆。

若子结点中有最大元素,将 A[i] 与其交换,对该子树调用 MAX_HEAPIFY。若 A[ i ] 为最大元素,结束循环。 

MAX_HEAPIFY 作用于一个高度为 h 的结点所需的运行时间为 O(h)。

    void maxHeapify(int i) {
        int l = left(i);
        int r = right(i);
        int largest = i;
        if (l <= heapSize && A[l] > A[largest]) largest = l;
        if (r <= heapSize && A[r] > A[largest]) largest = r;
        if (largest != i) {
            swap(A[i],A[largest]);
            maxHeapify(largest);
        }
    }


【练习】

6.2-1 图示出MAX_HEAPIFY(A,3)作用于数组A=<27,17,3,16,13,10,1,5,7,12,4,8,9,0>的过程。




6.2-2 由过程MAX_HEAPIFY开始,写出进行对应的最小堆操作的MIN_HEAPIFY(A,i)过程的伪代码,并比较MIN_HEAPIFY与MAX_HEAPIFY的运行时间。

    void minHeapify(int i) {
        int l = left(i);
        int r = right(i);
        int smallest = i;
        if (l <= heapSize && A[l] < A[smallest]) smallest = l;
        if (r <= heapSize && A[r] < A[smallest]) smallest = r;
        if (smallest != i) {
            swap(A[i],A[smallest]);
            minHeapify(smallest);
        }
    }

运行时间相同。


6.2-3 当元素 A[ i ] 比其两子女的值都大时,调用 MAX_HEAPIFY(A,i) 的效果是什么?

不进行操作,程序结束。


6.2-4 对 i > heap_size[A]/2,调用 MAX_HEAPIFY(A,i)的结果怎样?

由6.1的证明可知,i是叶子结点,当i没有子结点时,程序结束。


6.2-5 MAX_HEAPIFY的代码效率较高,但第十行中的递归调用可能例外,它可能使某些编译程序产生出低效的代码。请用迭代的控制结构(循环)取代递归结构,从而写一个更为高效的MAX_HEAPIFY。

    void maxHeapify_NonRecursive(int i) {
        while (true) {
            int l = left(i);
            int r = right(i);
            int largest = i;
            if (l <= heapSize && A[l] > A[largest]) largest = l;
            if (r <= heapSize && A[r] > A[largest]) largest = r;
            if (largest == i) break;
            swap(A[i],A[largest]);
            i = largest;
        }
    }


6.2-6 证明:对一个大小为n的堆,MAX_HEAPIFY 的最坏运行时间为Ω(lgn)。

设有n个结点的堆高度为h。由堆的定义可知,根节点到叶子结点最多比较 h 次,即 logn 次。

因此最坏运行时间为Ω(lgn)。






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