二维数组查找关键字

需求:

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

例如一个二维数组:

1  2  8  9

2  4  9  12

4  7  10  13

6  8  11  15

要查找的整数为 7

输出的结果应该是 3行2列

 

分析:

思路一

按照最简单的办法,从二维数组第一个元素从左到右从上到下开始遍历,直到找到或者遍历到最后一个元素找不到的情况。暂且把这种方法称之为从头遍历法吧。如果是m行n列的数组,则这种方法的时间复杂度是O(m*n)。请看示例代码findKeyFromHead

 

思路二

更高效的查找方法,从右上角开始遍历,暂且命名为右上角查找法吧。要找的整数是7,先比较右上角第一个元素9,

1.比较7和9,由于7比9小,数组左边的数比较小,下边的数比较大,因此7只能在9的左边;

2.比较7和8,由于7比8小,跟上面一样,7只能在8的左边;

3.比较7和2,由于7比2大,数组左边的数比较小,下边的数比较大,因此7只能在2的下边;

4.比较7和4,由于7比4大,跟上面一样,因此7只能在4的下边;

5.比较7和7,发现找到了结束循环。

如果比较过程中出现行数或者列数其中之一到0了还是找不到,说明这个数就不在数组中了。

右上角查找法每次比较都能排除调一整行或者一整列,时间复杂度是O(m+n)。

请看示例代码findKeyFromRrightHead

 

总结:

由于从头遍历法,每次只能排除一个元素,而右上角查找法每次能排除一整行和一整列,因此显而易见右上角查找法的效率会比较高。(PS.左下角查找法原理类似)

 

c++示例代码:

  1 #include <iostream>
  2 
  3 using namespace std;
  4 
  5 const int g_matrixRow = 4;
  6 const int g_matrixColumn = 4;
  7 
  8 /************************************************************************/
  9 /* @brif 从头遍历法查找二维数组关键字
 10 /* @param matrix 用于查询的二维数组
 11 /* @param row 二维数组的行数
 12 /* @param column 二维数组的列数
 13 /* @param key 需要查询的关键字
 14 /* @param retRow 关键字所在行(查询失败为默认值-1)
 15 /* @param retColumn 关键子所在列 (查询失败为默认值-1)
 16 /* @return true表示查找到 false表示查找失败
 17 /************************************************************************/
 18 bool findKeyFromHead(const int *matrix, const int row, const int column, const int key, int& retRow, int& retColumn)
 19 {
 20     bool bFoud = false;
 21     retRow = -1;
 22     retColumn = -1;
 23 
 24     if (!matrix || row < 1 || column < 1 || !retRow || !retColumn)
 25     {
 26         return bFoud;
 27     }
 28 
 29     for (int i = 0; i < row; ++i)
 30     {
 31         for (int j = 0; j < column; ++j)
 32         {
 33             //判断matrix[i][j]是不是跟key相同
 34             if (*(matrix+(i*column)+j) == key)
 35             {
 36                 bFoud = true;
 37                 //计算机索引从0开始,转换成真正的行数和列数
 38                 retRow = i + 1;
 39                 retColumn = j + 1;
 40                 break;
 41             }
 42         }
 43     }
 44     return bFoud;
 45 }
 46 
 47 /************************************************************************/
 48 /* @brif 右上角查找法查找二维数组关键字
 49 /* @param matrix 用于查询的二维数组
 50 /* @param row 二维数组的行数
 51 /* @param column 二维数组的列数
 52 /* @param key 需要查询的关键字
 53 /* @param retRow 关键字所在行(查询失败为默认值-1)
 54 /* @param retColumn 关键子所在列 (查询失败为默认值-1)
 55 /* @return true表示查找到 false表示查找失败
 56 /************************************************************************/
 57 bool findKeyFromRrightHead(const int *matrix, const int row, const int column, const int key, int& retRow, int& retColumn)
 58 {
 59     bool bFoud = false;
 60     retRow = -1;
 61     retColumn = -1;
 62 
 63     if (!matrix || row < 1 || column < 1 || !retRow || !retColumn)
 64     {
 65         return bFoud;
 66     }
 67 
 68     //从右上角开始查找,即第一个比较的原始是matrix[0][column-1]
 69     int tmpRow = 0;
 70     int tmpColumn = column - 1;
 71 
 72     //如果行数和列数都是合法的就一直循环
 73     while (tmpColumn >= 0 && tmpRow >= 0)
 74     {
 75         //判断matrix[tmpRow][tmpColumn]与关键字是否相等
 76         int curKey = *(matrix + column * tmpRow + tmpColumn);
 77         //相等表示找到了,保存当前的和列,退出循环
 78         if (key == curKey)
 79         {
 80             //计算机索引从0开始,转换成真正的行数和列数
 81             retRow = tmpRow + 1;
 82             retColumn = tmpColumn + 1;
 83             bFoud = true;
 84             break;
 85         }
 86         //关键字比当前的值大,说明在下边的行
 87         else if (key > curKey)
 88         {
 89             tmpRow += 1;
 90         }
 91         //关键字比当前的值小,说明在左边的列
 92         else
 93         {
 94             tmpColumn -= 1;
 95         }
 96     }
 97 
 98     return bFoud;
 99 }
100 
101 int main()
102 {
103     int matrix[g_matrixRow][g_matrixColumn] = { {1,2,8,9}, {2,4,9,12}, {4,7,10,13}, {6,8,11,15} };
104 
105     cout << g_matrixRow << "" << g_matrixColumn << "列的二维数组:" << endl << endl;;
106     for (int i = 0; i < g_matrixRow; ++i)
107     {
108         for (int j = 0; j < g_matrixColumn; ++j)
109         {
110             cout << matrix[i][j] << "\t";
111         }
112         cout << endl;
113     }
114     cout << endl;
115 
116     int key = 7;
117     int retRow = 0, retColumn = 0;
118 
119     bool bResult = findKeyFromHead((const int*)matrix, g_matrixRow, g_matrixColumn, key, retRow, retColumn);
120 
121     cout << "从头遍历法" << endl;
122     if (bResult)
123     {
124         cout << "关键字" << key << "在:"<< retRow << "" << retColumn << "" << endl;
125     }
126     else
127     {
128         cout << "关键字" << key << "没找到" << endl;
129     }
130 
131     bResult = findKeyFromRrightHead((const int*)matrix, g_matrixRow, g_matrixColumn, key, retRow, retColumn);
132 
133     cout << endl << "右上角查找法" << endl;
134     if (bResult)
135     {
136         cout << "关键字" << key << "在:" << retRow << "" << retColumn << "" << endl;
137     }
138     else
139     {
140         cout << "关键字" << key << "没找到" << endl;
141     }
142 
143     cout << endl;
144     return 0;
145 }

测试结果:

 

posted @ 2019-07-11 17:42  纯情小浩浩  阅读(125)  评论(0编辑  收藏