杨氏矩阵查找

在某个矩阵中,每行元素是递增的,每列元素也是递增的。即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; 
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值