数组,占据一块连续内存并按照顺序存储数据的一种最简单的数据结构。
数组的空间效率不好,经常会有空闲的区域没有得到充分利用。
数组的时间效率较好,可以根据下标在O(1)时间读写任何元素。
可以利用数组来实现简单哈希表O(1)查找:以数组下标作为哈希表的键值key,以数组中的每一个数字作为哈希表的值(value).
值得注意的是,当数组作为函数的参数进行传递时,数组会自动退化为同类型的指针。
题目:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该数。
最直接的思路,把二维数组画成矩形,然后从数组中选取一个数字,分3种情况考虑。
当数组选取的数字==要查找的数字,结束查找;
当数组选取的数字<要查找的数字,继续查找当前选取位置的右边或者下边;
当数组选取的数字>要查找的数字,继续查找当前选取位置的上边或者左边。
通过上面的分析,如果要查找的数字相对于当前选取的位置有可能在两个区域中出现,而且这两个区域还有重叠,问题就很复杂。
复杂的原因在于貌似越往下找,就陷得越深,我们需要找到一种方法,能够一边找,一边尽可能地筛出较多的不满足的数据。
思考一下,该题一直在强调一种关系:严格的大小关系。
如果能够把尽可能多的数字按顺序排好,那么是不是就可以实现每一次查找筛除比它小或比它大的数据。
可以发现这样一个顺序排列:
是不是很明显,我们可以从右上角入手!
如果该数字等于要查找的数字,查找结束;
如果该数字大于要查找的数字,剔除这个数字所在列;
如果该数字小于要查找的数字,剔除这个数字所在行
bool Find(int* matrix,int rows,int columns,int number)
{
bool found=false;
if(matrix!=NULL && rows>0 && columns>0)
{
int row=0;
int column=columns-1;
while(row<rows && column>=0)
{
if(matrix[row*columns+column]==number)
{
found=true;
break;
}
else if(matrix[row*columns+column]>number)
--column;
else
++row;
}
}
return found;
}
同理,也可以选择左下角的数字,只要满足顺序排列即可。
但是不可选择左上角或者右下角!否则无法缩小查找范围。
下面贴出完整的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
bool Find(int* matrix,int rows,int columns,int number)
{
bool found=false;
if(matrix!=NULL && rows>0 && columns>0)
{
int row=0;
int column=columns-1;
while(row<rows && column>=0)
{
if(matrix[row*columns+column]==number)
{
found=true;
break;
}
else if(matrix[row*columns+column]>number)
--column;
else
++row;
}
}
return found;
}
void test(string testname,int* matrix,int rows,int columns,int number,bool expected)
{
if(testname!="")
cout<<testname<<" begins:";
bool result=Find(matrix,rows,columns,number);
if(result==expected)
cout<<"pass!"<<endl;
else
cout<<"failed!"<<endl;
}
void test_1()
{
int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
test("Test1", (int*)matrix, 4, 4, 7, true);
}
void test_2()
{
int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
test("Test2", (int*)matrix, 4, 4, 5, false);
}
void test_3()
{
int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
test("Test3", (int*)matrix, 4, 4, 1, true);
}
void test_4()
{
int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
test("Test4", (int*)matrix, 4, 4, 15, true);
}
void test_5()
{
int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
test("Test5", (int*)matrix, 4, 4, 0, false);
}
void test_6()
{
int matrix[][4] = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
test("Test6", (int*)matrix, 4, 4, 16, false);
}
void test_7()
{
test("Test7",NULL, 0, 0, 16, false);
}
int main()
{
test_1();
test_2();
test_3();
test_4();
test_5();
test_6();
test_7();
return 0;
}
在codeblocks 17.0下的测试结果: