算法导论6-3习题解答(Young氏矩阵)

CLRS 6-3 :Young氏矩阵( 杨氏矩阵) 
解答:
(a)2         4       9       12
    3         5       14      Max
    8       16      Max    Max
    Max   Max    Max    Max
(b)Y[1, 1]为Max的话,那么按照Young氏矩阵定义,矩阵中其他数值必然大于等于它,所以Y为空。
    若Y[m, n] < Max的话,由其他元素都小于等于Y[m, n]可知此矩阵是满的。
(c)算法思想:
    1)A[0][0]必然是最小值,将其取出,然后将矩阵的最后一个元素A[m-1[n-1]补到第一位来,并将A[m-1[n-1]设置为Max
    2)将A[0][0]与A[0][1]和A[1][0]二者之间的最小值进行交换,
    3)若交换的是A[0][1],则在下一步对m*(n-1)矩阵的第一个元素重复2,
       若交换的是A[1][0],则在下一步对(m-1)*n矩阵的第一个元素重复2
    总之每次总是将第一个元素与其周边元素进行比较而已。
   

#include < iostream >
using  namespace std;
// 假设MAX为无穷大
#define MAX 1000000
int extract_min( int ** a, int m, int n);
void young_matrixify( int ** a, int i, int j, int m, int n);
int main()
{
int a[ 4 ][ 4 ] = { 2 , 4 , 9 , 12 , 3 , 5 , 14 , MAX, 8 , 16 , MAX, MAX, MAX, MAX, MAX, MAX};
// 打印数组a,可以看出它符合young氏矩阵的定义
for ( int i = 0 ; i < 4 ; i ++ )
{
for ( int j = 0 ; j < 4 ; j ++ )
cout
<< a[i][j] << " \t " ;
cout
<< endl;
}

int ** b = new  int * [ 4 ];
for ( int i = 0 ; i < 4 ; i ++ )
b[i]
= new  int [ 4 ];
for ( int i = 0 ; i < 4 ; i ++ )
{
for ( int j = 0 ; j < 4 ; j ++ )
b[i][j]
= a[i][j];
}
// 第一次取出最小值
extract_min(b, 4 , 4 );
// 打印取出最小值之后的young氏矩阵
for ( int i = 0 ; i < 4 ; i ++ )
{
for ( int j = 0 ; j < 4 ; j ++ )
cout
<< b[i][j] << " \t " ;
cout
<< endl;
}
// 再次取出最小值
extract_min(b, 4 , 4 );
// 打印取出最小值之后的young氏矩阵
for ( int i = 0 ; i < 4 ; i ++ )
{
for ( int j = 0 ; j < 4 ; j ++ )
cout
<< b[i][j] << " \t " ;
cout
<< endl;
}
return  0 ;
}
int extract_min( int ** a, int m, int n)
{
int temp = a[ 0 ][ 0 ];
a[
0 ][ 0 ] = a[m - 1 ][n - 1 ];
a[m
- 1 ][n - 1 ] = MAX;
young_matrixify(a,
0 , 0 , m, n);
return temp;
}
// 分了四种情况进行讨论,以i,j是否到达边界为区分点
void young_matrixify( int ** a, int i, int j, int m, int n)
{
if (i < m && j < n)
{
int ii = i;
int jj = j;
if (i + 1 < m && j + 1 < n && a[i + 1 ][j] > a[i][j + 1 ])
{
int temp = a[i][j];
a[i][j]
= a[i][j + 1 ];
a[i][j
+ 1 ] = temp;
jj
= j + 1 ;
}
else  if (i + 1 < m && j + 1 < n && a[i + 1 ][j] < a[i][j + 1 ])
{
int temp = a[i][j];
a[i][j]
= a[i + 1 ][j];
a[i
+ 1 ][j] = temp;
ii
= i + 1 ;
}
else  if (i + 1 < m && j + 1 == n && a[i + 1 ][j] < a[i][j])
{
int temp = a[i][j];
a[i][j]
= a[i + 1 ][j];
a[i
+ 1 ][j] = temp;
ii
= i + 1 ;
}
else  if (j + 1 < n && i + 1 == m && a[i][j + 1 ] < a[i][j])
{
int temp = a[i][j];
a[i][j]
= a[i][j + 1 ];
a[i][j
+ 1 ] = temp;
jj
= j + 1 ;
}
if (ii != i || jj != j)
young_matrixify(a, ii, jj, m, n);
}
}


(d)其实插入与(c)中的取出操作大同小异,将插入元素放入未满位置,然后比较相邻元素,直至相邻元素都比它小。
(e)所有的数首先插入到矩阵中所用时间为n^2*O(2n),然后取出操作为n^2*O(2n),加起来化简之后即为O(n^3)。
(f)算法思想:
   从A[m-1][0],即左下角开始寻找,比较相邻元素,然后不断循环至m*(n-1)或(m-1)*n矩阵,画画图就很明了了。
   下列代码加入上面代码中即可。

// goal为寻找的数字,m,n为维数
bool find( int ** a, int goal, int m, int n)
{
int mm = m;
int nn = n;
while (m > 0 && n > 0 )
{
if (a[m - 1 ][nn - n] == goal)
{
return  true ;
}
else  if (a[m - 1 ][nn - n] > goal)
-- m;
else  if (a[m - 1 ][nn - n] < goal)
-- n;
}
return  false ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值