• 杨氏矩阵查找


    在某个矩阵中,每行元素是递增的,每列元素也是递增的。即a[i][j]<a[i+1][j]且a[i][j]<a[i][j+1]。例如下列矩阵:

    4 7 11 15

    5 8 12 19

    6 9 16 22

    13 14 17 24

    21 23 26 30,这便是一个杨氏矩阵。

    要在这样的矩阵中查找某个数值元素的位置,或者判断某个数值在不在这个矩阵中。

    1.线性法。每次都找最右上角的元素,如果要查找数字(target)大于右上角的数字,则向下移动(删除右上方元素所在一行),若要查找数字(target)小于右上角的数字,则向左移动(删除右上方元素所在一列),要在上述矩阵中查找21,首先21与15比较,21>15,因此删除第一行,右上方的元素变为19,21>19,删除19所在的第二行,右上方元素变为22,21<22,删除22所在的一列,右上方元素变为16,21>16,删除16所在的一行,右上方元素变为17,21>17,删除17所在的一行,右上角元素变为26,21<26,删除26所在的一列,右上角元素变为23,21<23,删除23所在的一列,右上方元素变为21,成功!如下图所示:


    //杨氏查找线性搜索算法 
    #include<iostream>
    #include<vector>
    #define max 100
    using namespace std;
    vector<int>  Young1(int array[][4],int row,int col,int target)
    {
        vector<int> v;
        int begin_row = 0;
        int begin_col = col-1;
        if(target < array[0][0] || target > array[row-1][col-1])
        {
            v.push_back(-1);
            v.push_back(-1);
            return v;
        }
        while(begin_row < row && begin_col >= 0)
        {
            if(target > array[begin_row][begin_col])
            begin_row ++;
            else if(target < array[begin_row][begin_col])
            begin_col --;
            else 
            {
                 v.push_back(begin_row);
                 v.push_back(begin_col);
                 return v;
            }
        }
        v.push_back(-1);
        v.push_back(-1);
        return v;
          
    }
    int main(void)
    {
        int array[5][4]={4,7,11,15,5,8,12,19,6,9,16,22,13,14,17,24,21,23,26,30};
        vector<int> result = Young1(array,5,4,21);
        for(vector<int>::iterator it = result.begin();it != result.end();it ++)
        {
           cout<<*it<<endl;
        } 
        system("pause");
        return 0; 
    }
    

    最坏时间复杂度O(N+M)。线性时间内完成。

    2.分治法。首先以矩阵中间元素为中心将矩阵分为四部分,下图为例,以⑨为中心分为红色1,2,3,4部分,如果查找的元素大于9,例如查找21,因为1号区域内部的元素全部小于9,因此只需要在2,3,4区域内部查找即可;如果查找的元素小于9,4号区域内部的元素全部大于9,因此只需要在1,2,3区域内部查找即可。

    #include<iostream>
    #define max 100
    using namespace std;
    /*
    row,col--行数,列数
    lr lc矩阵左上角坐标
    rr rc矩阵右上角坐标
    target 要查找的数 
    result_row ,result_col 目标坐标
    */
    bool Young2(int array[][4],int row,int col,int target,int lr,int lc,int rr,int rc,int &result_row,int &result_col)
    {
        if(lr>rr||lc>rc) 
        {
                  result_row = -1;
                  result_col = -1;
                  return false;
        }
        if(target < array[lr][lc] || target > array[rr][rc])
        {
                  result_row = -1;
                  result_col = -1;
                  return false;
        }
     
        int begin_row_index = (int)((lr+rr)/2);
        int begin_col_index = (int)((lc+rc)/2);
        if(array[begin_row_index][begin_col_index]==target) 
        {
            result_row = begin_row_index;
            result_col = begin_col_index;
            return true;    
        }
        else if(array[begin_row_index][begin_col_index] < target)
        {
            return Young2(array,row,col,target,begin_row_index+1,begin_col_index+1,rr,rc,result_row,result_col)//4号区域
                 ||Young2(array,row,col,target,lr,begin_col_index+1,begin_row_index,rc,result_row,result_col)//2
                 ||Young2(array,row,col,target,begin_row_index+1,lc,rr,begin_col_index,result_row,result_col);//3
        }
        else
        {
            return Young2(array,row,col,target,lr,lc,begin_row_index,begin_col_index,result_row,result_col)//1
                 ||Young2(array,row,col,target,lr,begin_col_index+1,begin_row_index,rc,result_row,result_col)//2 
                 ||Young2(array,row,col,target,begin_row_index+1,lc,rr,begin_col_index,result_row,result_col);//3
        }
          
    }
    int main(void)
    {
        int array[5][4]={4,7,11,15,5,8,12,19,6,9,16,22,13,14,17,24,21,23,26,30};
        int a,b;
        bool r = Young2(array,5,4,21,0,0,4,3,a,b);
        cout<<r<<","<<a<<";"<<b<<endl;
        system("pause");
        return 0; 
    }
    



  • 相关阅读:
    liunx 利用管道线kill多个进程
    将多个学生平均分配到多个学校的方法示例
    mysql 根据查询条件进行update
    Mysql 使用临时表比较数据差异以及 临时表的优化
    Netcore 将汉字转化为拼音
    mysql 清除多列重复数据,只保留其中一条
    使用Mysql 存储过程和游标进行同步数据
    Culture is not supported. (Parameter 'name') u0002� is an invalid culture identifier.
    Swagger 过滤特定控制器配置方法(Swashbuckle.AspNetCore 5.0.0)
    System.Linq Distinct 方法使用
  • 原文地址:https://www.cnblogs.com/sunp823/p/5601427.html
Copyright © 2020-2023  润新知