zoukankan      html  css  js  c++  java
  • 算法导论 第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"
  • 相关阅读:
    我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比(转载)
    spring boot 使用application.properties 进行外部配置
    Nginx+Springboot+Vue 前后端分离 解决跨域问题
    windows7下RabbitMQ的安装
    七牛云 如何配置域名的 CNAME
    springboot接口 接收参数为实体对象跟MultipartFile对象报错。
    数据库性能优化之SQL语句优化(下)
    数据库性能优化之SQL语句优化(上)
    七个对我最好的职业建议
    程序员最艰巨的十大任务
  • 原文地址:https://www.cnblogs.com/bigrabbit/p/2531758.html
Copyright © 2011-2022 走看看