算法导论 第6章堆排序 课后习题

6.5-7  Heap-DELETE(A, i)操作结点i中的项从堆A中删去。对含n个元素的最大堆,请给出时间为O(lgn)的HEAP-DELETE的实现。

    Heap-DELETE(A, i)
        del_val   ←  A[i] 
        if i = heap-size[A]
            then heap-size[A] ← heap-size - 1
                   return del_val
        HEAP-INCREASE-KEY(A, i, key)
        HEAP-EXTRACT-MAX(A)
        return del_val
6.5-8    请给出一下时间为O(n*lgk),用来将 k 个已排序链表合并为一个排序链表的算法.此处,n 次所有输入链表中元素的总数.
    假设 k 个链表均为非空单向链表,带有头结点,且按递增排序的。数组L[k]存放k个链表的头结点。最终结果存在链表链表R。
    LIST-MERGE(L[k])
        create arrays A[1..k]
        create list R
        current ← head[R]
        heap-size[A] ← k
        for  ← 1 to k
            do A[i]  ← next[L[i]]
        BUILD-MAX-HEAP(A)
        while heap-size(A) > 0
            do min ← HEAP-MINIMUM(A)
                 next[current] ← min
                 current ←  min
                 if next[min] = NULL
                     then HEAP-EXTRACT-MINIMUM(A)
                     else
                         then A[1] ←  next[min]
                                  MIN-HEAPIFY(A)
   return R
 
思考题6-3
一个 m*n 的 Young 氏矩阵(Young tableau) 是一个 m*n 的矩阵,其中每一行的数据都从左到右排序,第一列的数据都从上到下排序.Young 氏矩阵中可能会有一些  ∞ 数据项,表示不存在的元素.所以,Young 氏矩阵可以用来存放 r<= mn 个有限的元素.

a).画一个包含{9,16,3,2,4,8,5,14,12} 的4*4 的Young 氏矩阵.

b).给出一个在非空 m*n 的 Young  氏矩阵上实现 EXTRACT-MIN 算法,使其运行时间为O(m+n).

c).说明如何在O(m+n)时间内,将一个新元素手入到一个未满的 m*n Young 氏矩阵中.

d).给出一个时间复杂度为 O(n^3) 的对 n*n Young 氏矩阵排序的算法.

f).给出一个运行时间为O(m+n) 的算法,来决定一个给定的数是否存在于一个给定的 m*n  的 Young 氏矩阵当中. 

row[A], col[A]分别为Young矩阵行与列数目。
b)
    算法分析
    设大小为m*n的Young氏矩阵A[1...m, 1...n],根据Young氏矩阵的性质,矩阵的最小值是为A[1,1]。因为A[2,1]、A[1,2]分别是子矩阵A[1..m-1, 1...n]和A[1...m, 1...n-1]的最小值,所以矩阵A的第二小的值为min(A[2,1],A[1,2])。假设min(A[2,1],A[1,2])= A[1,2],当EXTRACT-MIN(A)把矩阵A的最小值A[1,1]取出时,为保持Young氏矩阵的性质,需把A[1,2]移到 A[1,1]。此移动操作又导致了对子矩阵A[1...m, 1...n-1]进行了EXTRACT-MIN。因此在m*n的Young氏矩阵上实现EXTRACT-MIN的算法,可以使用一个递归的过程,通过解决(m-1)*n或m*(n-1)子问题来解决m*n问题。
    伪代码
    //Young氏矩阵为A,i,j为子矩阵的左上角的坐标 
    YOUNG-EXTRACT-MIN(A, i, j)
        min ← A[i, j]
        A[i, j] ← ∞
        if i < m and j < n
            then if A[i+1, j] < A[i, j+1]
                         then exchange(A[i, j], A[i+1, j])
                                  EXTRACT-MIN(A, i+1, j)
                         else
                                  exchange(A[i, j], A[i, j+1])
                                  EXTRACT-MIN(A, i, j+1) 
            else if i < m and j = n
                         then exchange(A[i, j], A[i+1, j])
                                  EXTRACT-MIN(A, i+1, j)
            else if i = m and j < n
                         then exchange(A[i, j], A[i, j+1])
                                  EXTRACT-MIN(A, i, j+1)
            else // i = m and j =n
        return min;
算法复杂度分析:
        m.n 分别为矩阵的行数与列数,P = m + n则推出递归式
        T(P) = T(P-1) + O(1)    P>2
                    O(1)                  P=2
        忽略边界条件,可得递归式T(P) = T(P-1) + c
        由递归树方法可得 T(P) = O(P)
c).    算法分析:
    由于Young氏矩阵未满,则A[m, n] =  ∞。然后将A[m, n]更新为插入值后,可能违反了Young氏矩阵的性质。所以需中采用了类似INSERT-SORT的插入循环方式,从插入节点[m, n]往矩阵的左上方移动,寻找合适的位置,保持Young氏矩阵的性质。在移动的过程中此元素不断与左侧(或上方)矩阵元素比较,如果此元素关键字小于左侧(或上方)元素,则交换它们的关键字,继续向左移动(或向上移动)。反复与左侧和上方元素比较,直至该元素均大于左侧和上方元素,程序终止。
 
    YOUNG-INSERT(A, key)
        A[row[A], col[A]] ← key
        i ← row[A]
        j ← col[A]
        while i ≥ 1 and j ≥ 1
           do if i > 1 and A[i - 1, j] > A[i, j]
                     then exchange(A[i -1, j], A[i, j]) 
                              i ← i - 1
                     else if j > 1 and A[i, j - 1] > A[i, j]
                                 then exchange(A[i, j -1], A[i, j]) 
                                          j ← j - 1
                                 else return;
  复杂度分析类似于b),T(P) = O(P)=O(m+n)
 
d). 算法分析,首先构造一个n*n矩阵A,元素均赋值为∞,满足Young氏性质,将n*n个元素逐个调用 YOUNG-INSERT,插入矩阵A中。然后,调用YOU-G-EXTRACT-MIN(A, i, j) n*n次,并将返回值逐个插入数组中。
 
    YOUNG-SORT(C)
      create matrix A[1...n, 1...n]
      for i ← 1 to n
          do for j ← 1 to n
                  do A[i, j] ← ∞
      for i ← 1 to n*n
          do YOUNG-INSERT(A, C[i])
      for i ← 1 ton*n
          do C[i] = YOUNG-EXTRACT-MIN(A, 1, 1)
 
    复杂度分析:YOUNG-SORT过程时间代价为O(n3),其中每次调用YOUNG-INSERT与YOUNG-EXTRACT-MIN复杂度为O(n),共调用了n2次。
 
e).    
总是于最右上角的元素X比较;
1)如果==X,结束;
2)如果比X小,那么元素只可能在前N-1列中;
3)如果比X大,那么元素只可能在后M-1行中;
Young 氏矩阵去掉一行或一列还是 Young 氏矩阵;
所以每次比较最少去掉一行或一列,这样复杂度就是 O(m+n);

    SEARCH(A, key)
        m ← row[A]
        n ← col[A]
        i ← 0
        j ← n
        while i  ≤  n and j ≥ 1
            if A[i ,j] > key 
                then j ← j - 1 
                else if A[i ,j] < key
                    then i ← i - 1
                        else  return (i, j)
            return "Not Found"
原文地址:https://www.cnblogs.com/bigrabbit/p/2531758.html