《算法导论》第六章“堆排序”习题解答

《算法导论》第六章“堆排序”习题解答_第1张图片

6-1-1:  解: 最少的情况为第h层只有一个叶子节点,那么元素数为2h,最多的情况为该树是一颗完全二叉树,元素数为2h+1-1

6-1-2:  解:根据上一题我们可以知道,对于有n个元素的堆,必须满足如下式子: 2h <=  n  <=2h+1-1 < 2h+1,所以又h <= lgn < h+1,故h = └lgn┘

6-1-3:  解:假设该最大元素A不在根上,那么我们知道在这颗子树中,除了跟节点,其余节点都有父节点,那么A就要比父节点的数值大,与该树是最大堆相          盾,故最大元素A在子树的根上

6-1-4:  解:最小元素只可能在叶子节点上

6-1-5:  解:是最小堆,满足最小堆的性质

6-1-6:  解:不是,元素为6的节点,它的右子节点为元素7,

6-1-7:  解:另第一个叶子节点为i,则有 (i-1)*2 +1 <= n,i*2> n,所以很容易得知得一个叶子节点为  i = └n/2┘+1 

《算法导论》第六章“堆排序”习题解答_第2张图片

6-2-1:  解:  略(不好写)

6-2-2:  解:  MIN-HEAPIFT(A,i)

          l <- Left(i)

          r <- Right(i)

          if l <= heap-size(A) and A[i] > A[l]

            then smallest <- l

            else  smallest <- i

          if r <= heap-size(A) and A[smallest] > A[r]

            then smallest <- r

          if smallest != i

            exchange A[i] and A[smallest]

            MIN-HEAPIFY(A,smallest);

        时间复杂度为O(lgn)

6-2-3:  解:不进行任何处理,直接返回

6-2-4:  解:不进行任何处理,直接返回

6-2-5:  解:MAX-HEAPIFT(A,i)

          while (true)

            l <- Left(i)

            r <- Right(i)

            if l <= heap-size(A) and A[i] < A[l]

              then largest <- l

              else  largest <- i

            if r <= heap-size(A) and A[smallest] < A[r]

              then largest <- r

            if largest != i

              then exchange A[i] and A[largest]

                 i <- largest

              else  break;

6-2-6:  解:当输入数组是一个排序好了的递增数组时,共需要调用lgn次MAX-HEAPIFY,每次调用都是O(1)时间,所以整个算法最坏运行时间为O(lgn)

《算法导论》第六章“堆排序”习题解答_第3张图片

6-3-1:  解:略

6-3-2:  解:因为调用MAX-HEAPIFY子程序的时候必须要保证它的左右子树是最大堆性质,而从1开始的话,显然它的左右子树不是最大堆性质的子树

6-3-3:  解:略

《算法导论》第六章“堆排序”习题解答_第4张图片

6-4-1:  解: 25 13 20 8 7 17 2 5 4    20  13  17  8 7 4 2 5 25  17  13  5  8  7  4  2  20  25

         13  8  5  2  7  4  17 20 25  8 7 5 2 4 13 17 20 25   7 4 5 2 8 13 17 20 25

        5 4 2  7 8 13 17 20 25    4 2 5 7 8 13 17 20 25    2 4 5  7 8 13 17 20 25

6-4-2:  解:初始: 初始态的时候i=n,故很显然循环不变式是正确的

        保持: 因为迭代每一次都是将前i个元素中最大的一个放到了前i个元素序列的末尾,而这个最大元素根据前面的迭代过程很显然是小于后面i+1.....n        个元素的,故保持了这一性质

        终止: 终止时i=1,表明后面2.....n个元素是排好序的,且都大于第一个元素,故整个序列是排好序的

6-4-3:  解:O(nlgn)和Ω(nlgn)

6-4-4:  解:当输入的数组是不同时,Build-Heap时间复杂度为O(n),每一次调换元素都破换了原有最大堆的性质,故为Ω(nlgn)

《算法导论》第六章“堆排序”习题解答_第5张图片

6-5-1:  解:为 13 12 9 5 6 8 7 4 0 1 2 15

6-5-2:  解:为 15 13 10 5 12 9 7 4 0 6 2 1 8

6-5-2:  解:HEAP_MIN(A)

          return A[1]

        HEAP_EXTRACT_MIN(A)

          min<-A[1]

          A[1] <- A[heap-size(A)]

          heap-size(A) <- heap-size(A)-1

          MIN_HEAPIFY(A,1)

        HEAP_DECREASE_KEY(A,i,key)

          if A[i] < key

            then return error

          A[i] <- key

          while i>1 and A[parent(i)]>A[i]

            exchange A[i] and A[parent[i]]

            i<- parent(i)

6-5-4:  解:因为HEAP_INCREASE_KEY会比较key和A[i]的大小,如果key要小于A[i]就直接返回了

6-5-5:  解:初始:即A[i]的值增加到key,则整个最大堆就在节点i发生了增大,很明显,循环不变式是对的

        保持:当迭代的过程中,发生了交换,那么狠明显,节点i的子树肯定保持了最大堆性质,而整个树唯一有可能不满足最大堆的性质的只可能发生在            i=paranet(i)节点上。循环不变式也成立

        终止:如果数在i>1的情况下终止的话,那么数肯定是一个最大堆数,而如果在i<1的情况下终止,因为此时已经到达根节点了,而在根节点下面仍           然保持了最大堆性质

6-5-7:  解:思路:想增大节点i的值,让它上移到根节点,然后删除根节点,

6-5-8:  解:思路:建立一个大小为k的数组,然后将k个链表的第一个元素压入数组,构建最小堆(O(lgk)),然后取出最小元素min,然后将min->nodeNext压入数组,构建最小堆,重复操作  

《算法导论》第六章“堆排序”习题解答_第6张图片     

6-1:   解:a、不一样,如当输入数组为 8 5 3 9 2 4 6 7,BUILD_MAX_HEAP为: 9 8 6 7 2 4 3 5,而INSERT为:9 8 6 7 2 3 4 5

        b、对于每次插入为logn,共n次插入,故为O(nlogn)

《算法导论》第六章“堆排序”习题解答_第7张图片

6-2:   解:a、节点i的父节点为:(i-2)/d+1向上取整,第一个子节点为(i-1)d+2,一次类推到第d个子节点

        b、树的高度为logdn向下取整

        c、max = A[1]

          A[1] <- max[heap-size(A)]

          heap-size(A) = heap-size(A)-1

          Max-Heapify(A,1)

        运行时间为O(dlogdn)

        d、heap-size(A) <- heap-size(A)+1

          A[heap-size(A)] = -∞

          Heap-Increase-key(A,heap-size(A),key);

           运行时间为O(logdn);

        e、 if key <A[i]  then return

          A[i] = key

           while i>1 and A[parent(i)] < A[i]

            exchange A[i] and A[parent(i)]

            i <- parent(i);

         运行时间为O(logdn);

《算法导论》第六章“堆排序”习题解答_第8张图片

6-3:  解: a、 2   3   4   5

         8   9   12 14

                       16 ∞   ∞  ∞

           ∞ ∞   ∞  ∞

      b、因为Y[1,1] = ∞,那么对于m*n矩阵,第一行和第一列的所有元素必然为∞(因为是排好序的),对于对于矩阵中的任意一个元素Y(i,j),如果该        元素不为空,那么它左边和上边的元素必然不为空,即Y(1,j)和Y(i,1)不为空,相矛盾,故得证,同理可得正第二个命题

      c、可以利用类似于max_heapify的递归思想,将最小元素A[1,1]取出后再用∞赋值A[1,1],然后对交换后的矩阵左上角元素进行递归操作            reverse_young_min_heapify,直到整个矩阵符合Young氏矩阵的规则。T(p) = T(p-1) + O(1),解递归式易得:T(p) = O(m+n)。

      d、也是利用堆的思想,先将A[m,n]赋值为待插入元素,然后进行堆化递归操作即可。

      e、利用extract_min易证。

      f、思路是从矩阵右上角开始,如果该元素==k,则找到;如果该元素<k,则删去最上行,重复操作;如果该元素>k,则删去最右行,重复操作

 

如有错误,或是更好的解答方法,望路过的牛人指出,谢谢

 

你可能感兴趣的:(算法导论)