《算法导论》第6章 堆排序 (4)Young氏矩阵

53 篇文章 1 订阅



1. 什么是Young氏矩阵?

一个 m * n 的矩阵,其中每一行的数据都从左到右排序,每一列的数据都从上到下排序。
其中用 ∞ 代表不存在的元素,一共可以存放 r ≤ mn 个有限的数。

如下面程序实现中用来测试的Young氏矩阵:

{ 1,  3,   5,  7,    8,   11 }
{ 4,  6,   9,  14,  15,  19 }
{ 10, 21, 23, 33, 56,  57 }
{ 34, 37, 45, 55, 
∞,  ∞ }


2. 相关问题及思路

2.1 实现EXTRACT-MIN的算法,使其运行时间为O(m + n)。

参考最大堆的方法MAX-HEAPIFY,两者的相似性是:一个元素 i 的改变,破坏了
堆和Young氏矩阵的性质。MAX-HEAPIFY从 i 的左右子结点中选出最大者 j ,
拷贝到被取出的 i 的位置。这样 j 处的性质又被破坏,然后递归地继续处理这个结点位置。

EXTRACT-MIN也可以这样处理,思路是相同的。
两个问题都可以归纳为:根结点被取出后,数据结构性质被破坏,递归地进行局部调整。


2.2 查找一个元素在矩阵中是否存在。

需要从右上角的元素开始向左向下遍历,比如上面矩阵中的元素11。
假如要查找14,14比11大则向下继续比较,14比19小则向左走。

不能从左上角的元素1开始遍历,因为向右的3和向下的4都比1大,没法决定往哪个方向遍历。


3. 代码实现及注释

#include <stdio.h>

// 与MAX-HEAPIFY很像,找出右边元素和下边元素中的较小者,
// 如果没处理到边界,就继续递归处理。
void youngify(int matrix[][6], int row, int col, int i, int j)
{
     int minI, minJ;
     if (i < row - 1) {
          minI = i + 1;
          minJ = j;
     } else {
          minI = i;
          minJ = j;
     }
     if (j < col - 1 && matrix[i][j + 1] < matrix[minI][minJ]) {
          minI = i;
          minJ = j + 1;
     }

     if (minI != i || minJ != j) {
          matrix[i][j] = matrix[minI][minJ];
          youngify(matrix, row, col, minI, minJ);
     }         
}

int extract_min(int matrix[][6], int row, int col)
{
     int min = matrix[0][0];
     youngify(matrix, row, col, 0, 0);    
     return min;
}

// 从最右上角开始,比要搜索元素x大则向左,
// 比要x小则向下。
int search(int matrix[][6], int row, int col, int x)
{
     int i = 0;
     int j = col - 1;

     while (i < row && j >= 0) {
          if (matrix[i][j] == x)
               return 1;
          else if (matrix[i][j] > x)
               j--;
          else
               i++;
     }

     return 0;
}

void printMatrix(int matrix[][6], int row, int col)
{
     int i, j;
     for (i = 0; i < row; i++) {
          for (j = 0; j < col; j++)
               printf("%d, ", matrix[i][j]);
          printf("\n");
     }
     printf("\n");
}

int main(void)
{
     int matrix[][6] = {
          { 1,  3,  5,  7,  8,  11 },
          { 4,  6,  9,  14, 15, 19 },
          { 10, 21, 23, 33, 56, 57 },
          { 34, 37, 45, 55, 100, 100 }
     };

     extract_min(matrix, 4, 6);
     printMatrix(matrix, 4, 6);
     
     printf("%d\n", search(matrix, 4, 6, 46));
     printf("%d\n", search(matrix, 4, 6, 21));

     return 1;
}





  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值