k路归并 Young氏矩阵的相关算法(转)

二.基于堆的K路合并问题.

题:请给出一下时间为O(n*lgk),用来将 k 个已排序链表合并为一个排序链表的算法.此处,n 次所有输入链表中元素的总数.

答:新建一个链表,再申请一个大小为 k 的数组A,首先把 k 个已排序链表的第一个元素压入 A 中,将 A 建成一个最小堆,花费O(k) 的时间.然后将堆 A 的第一个元素 min(也就是最小的那个)放入链表中.再将min->nextNode 放在min的位置.再花O(lgk)调用heapify 方法将 A 重新建成一个最小堆.然后又将第一个元素 min 放入链表......重复进行就可将 k 个已排序链表合并.(当最后剩余不到 k 个节点时情况会有点变化,但很容易解决).显然,这样处理的时间复杂为 O(n*lgk);

 三.Young 氏矩阵的相关算法.

题:一个 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 氏矩阵当中.

答.a).  2     3      4      5

          8     9     12    14

         16    ∞      ∞     ∞

          ∞     ∞      ∞     ∞        PS.该矩阵并不是唯一的.

    b). 用递归的思想.通过递归的解决(m-1)*n,或m*(n-1) 的子问题来求解.则有 T(m,n)=T(m-1,n) or T(m,n-1)+ O(1),显然,T=O(m+n).伪代码如下:

EXTRACT_MIN( Young[ x...m] [y...n])
   EXTRACT_MIN
= Young[x][y];  // 类似FORTRAN的写法.函数名即是返回值.
    if (x == m and y == n) Young[x][y] =  INFINITY;
   
if (Young[x + 1 ][y] > Young[x][y + 1 ])
          Young[x][y]
= EXTRACT_MIN(Young[x...m][y + 1 ...m]);
   
else  Young[x][y] = EXTRACT_MIN(Young[x + 1 ...m][y...m]);
END

      c).  这个就比较简单了.先将待插入的元素 K 放在 Young[m][n], 然后比较 K 与它左方或上方元素的大小,并与其中较大的一个交换.反复进行直到 K 不小于它左方和上方的元素为止. 在这里,同样有,T(m,n)=T(m-1,n) or T(m,n-1)+ O(1),T=O(m+n).伪代码如下:

INSERT(k,Young[m][n])
  
if (Young[m][n]  <  INFINITY)  alert: 矩阵已满,无法插入 !!
  
while (k < Young[m - 1 ][n] or k < Young[m][n - 1 ])
      
if (Young[m - 1 ][n]  > Young[m][n - 1 ])
          swap(k,Young[m
- 1 ][n]);
          m
= m - 1 ;
      
else
          swap(k,Young[m][n
- 1 ]);
          n
= n - 1 ;
END

            

     d). 调用 n*n 次 EXTRACT_MIN 过程即可.

       e). 同样是递归的思想.递归表达式与 b)中的相同.伪代码如下:

SEARCH(k,Young[x...m][y...n]
    
if (k < Young[x][y] or k > Young[m][n]  return   " NotFound " ;
    
if (k == Young[x][y])     return   " Found " ,x,y.
    
if (k < Young[x + 1 ][y]) SEARCH(k,Young[x...x][y + 1 ...n]
    
else  SEARCH(k,Young[x + 1 ...m][y...n]
END
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值