zoukankan      html  css  js  c++  java
  • 算法导论63习题解答(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;
    }
    ---
    可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
  • 相关阅读:
    sockjs-node/info?t=报错解决
    微信昵称表情符号前端显示问题
    vue-cli 3.0项目安装报错
    vue-cli项目按需引入element-ui实际操作
    javafx分别设置四个边框
    springmvc使用<mvc:default-servlet-handler/>导致的handler失效
    windows注册表删除右键菜单
    计算机实现32位整数加减乘除的方法
    常用排序算法
    AbstractCollection类中的 T[] toArray(T[] a)方法源码解读
  • 原文地址:https://www.cnblogs.com/null00/p/2065075.html
Copyright © 2011-2022 走看看