二維數組查找關鍵字

需求:

在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都是按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。若是含有該整數則把整數所在的行和列輸出。ios

例如一個二維數組:c++

1  2  8  9數組

2  4  9  12函數

4  7  10  13測試

6  8  11  15spa

要查找的整數爲 7code

輸出的結果應該是 3行2列blog

 

分析:

思路一

按照最簡單的辦法,從二維數組第一個元素從左到右從上到下開始遍歷,直到找到或者遍歷到最後一個元素找不到的狀況。暫且把這種方法稱之爲從頭遍歷法吧。若是是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 }

測試結果:

相關文章
相關標籤/搜索