题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
例如:
如果在这个数组中查找7,返回true。查找3,返回false。
1 | 2 | 8 | 9 |
2 | 4 | 9 | 12 |
4 | 7 | 10 | 13 |
6 | 8 | 11 | 15 |
我这个方法虽然能避免了相互重叠的区域,但是效率没有书上的算法好,但是作为一个锻炼写递归程序的机会也是不错的。
深色的为中心元素,有三种情况。
1.要找的值正好是中心元素
直接返回真。
2.要找的值大于中心元素,如图(a)
将(a)灰色部分进行查找。
分为两个矩形区域,如图横线,竖线所示。
3.要找的值小于中心的值,如图(b)
将(b)灰色部分进行查找。
分为两个矩形区域,如图横线,竖线所示。
查找不规则的区域需要知道一下信息:区域左上角的绝对坐标,区域的长 与 宽。所以我们可以设定一下函数原型。
bool BinarySearchMat(int* mat,int beginR,int beginC,int sumR,int sumC,int val);
根据上述的三种情况,写得一下代码。
bool BinarySearchMat(int* mat,int beginR,int beginC,int sumR,int sumC,int val)
{
if (sumC <= 0 || sumR <=0)
{
return false;
}
int halfR = sumR / 2;
int halfC = sumC / 2;
int midR = beginR + halfR;
int midC = beginC + halfC;
if (val == mat[ midR * N + midC])
{
return true;
}
if(val < mat[midR * N + midC]) // define N = 4;
{ //(b)图上面部分(横线)
if(BinarySearchMat(mat,beginR,beginC,halfR,sumC,val))
return true;
if (BinarySearchMat(mat,midR,beginC,sumR - halfR ,halfC ,val))//(b)图左边部分(竖线)
return true;
}
else
{// val > mat[midR * N + midC]
//(a)图下面部分(横线)
if(BinarySearchMat(mat,midR + 1,beginC,sumR - halfR - 1,sumC,val))
return true;
<span style="white-space:pre"> </span>//(a)图右边部分(竖线)
if (BinarySearchMat(mat,beginR,midC + 1,halfR + 1,sumC - halfC - 1,val))
return true;
}
return false;
}
测试驱动代码:
int main()
{
if(BinarySearchMat(arr[0],0,0,4,4,15))
cout<<"true"<<endl;
else
cout<<"false"<<endl;
if(BinarySearchMat(arr[0],0,0,4,4,7))
cout<<"true"<<endl;
else
cout<<"false"<<endl;
if(BinarySearchMat(arr[0],0,0,4,4,3))
cout<<"true"<<endl;
else
cout<<"false"<<endl;
return 0;
}
完整程序(环境:VS2012)
/*
二维数组的查找,
二维数组每行递增,每列递增
*/
#include <iostream>
int arr[4][4] = {1,2,8,9,2,4,9,12,4,7,10,13,6,8,11,15};
const int N = 4;
bool BinarySearchMat(int* mat,int beginR,int beginC,int sumR,int sumC,int val);
using namespace std;
int main()
{
if(BinarySearchMat(arr[0],0,0,4,4,15))
cout<<"true"<<endl;
else
cout<<"false"<<endl;
if(BinarySearchMat(arr[0],0,0,4,4,7))
cout<<"true"<<endl;
else
cout<<"false"<<endl;
if(BinarySearchMat(arr[0],0,0,4,4,3))
cout<<"true"<<endl;
else
cout<<"false"<<endl;
return 0;
}
bool BinarySearchMat(int* mat,int beginR,int beginC,int sumR,int sumC,int val)
{
if (sumC <= 0 || sumR <=0)
{
return false;
}
int halfR = sumR / 2;
int halfC = sumC / 2;
int midR = beginR + halfR;
int midC = beginC + halfC;
if (val == mat[ midR * N + midC])
{
return true;
}
if(val < mat[midR * N + midC])
{
if(BinarySearchMat(mat,beginR,beginC,halfR,sumC,val))
return true;
if (BinarySearchMat(mat,midR,beginC,sumR - halfR ,halfC ,val))
return true;
}
else
{// val > mat[midR * N + midC]
//xia
if(BinarySearchMat(mat,midR + 1,beginC,sumR - halfR - 1,sumC,val))
return true;
if (BinarySearchMat(mat,beginR,midC + 1,halfR + 1,sumC - halfC - 1,val))
return true;
}
return false;
}