您的位置:首页 > 编程语言 > C语言/C++

C++ 二维数组中的二分查找

2015-07-07 10:40 232 查看


在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

这样的矩阵有个性质,最左上角的元素必定是最小值,最右下角的是最大值,在一个m*n的矩阵中,类对角线:

i=(m1+m2)/2,j=(n1+n2)/2;

上的元素也是排好序的,通过对整体矩阵的一个行和列的二分查找,找到该矩阵类对角线上的中间点二维矩阵(左上角(m1,n1)比待查元素小,右下角(m2,n2)比待查元素大),然后递归查找这个中间矩阵相对的右上角的矩阵和左下角的矩阵即可。(因为左上角矩阵的元素都比(m1,n1)小,右下角的都比(m2,n2)大)

#include <iostream>
#include <stdio.h>

using namespace std;

int binSearch(int key,int **a,int n,int m1,int n1,int m2,int n2)
{
int begin_m1=m1,begin_n1=n1,end_m2=m2,end_n2=n2;
int i=(m1+m2)/2,j=(n1+n2)/2;
int left=0,right=0;
if(a==NULL)
return 0;
if(key<*(*(a+m1)+n1)||key>*(*(a+m2)+n2))
return 0;
else if(key==*(*(a+m1)+n1)||key==*(*(a+m2)+n2))
return 1;
while((i!=m1 || j!=n1) && (i!=m2 || j!=n2))
{
if(key==*(*(a+i)+j))
return 1;
else if(key<*(*(a+i)+j))
{
m2=i;
n2=j;
i=(m1+m2)/2;
j=(n1+n2)/2;
}
else
{
m1=i;
n1=j;
i=(m1+m2)/2;
j=(n1+n2)/2;
}

}

if(i<end_m2)
left=binSearch(key,a,n,i+1,begin_n1,end_m2,j);
if(j<end_n2)
right=binSearch(key,a,n,begin_m1,j+1,i,end_n2);
if(left||right)
return 1;

}

int main()
{
int m,n;
int key;
while(cin>>m>>n)
{
cin>>key;
int **a=new int *[m];
for(int i=0;i<m;i++)
a[i]=new int
;
int flag=0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
scanf("%d",(*(a+i)+j));
flag=binSearch(key,a,n,0,0,m-1,n-1);
if(flag==1)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: