楊氏矩陣young tableau,作為乙個既類似於二叉排序樹(bst),又類似於堆結構的一種簡單資料結構。乍看一下,其實就是乙個二維陣列,但是該資料結構有著明顯的特點,即陣列的每一行元素嚴格單調遞增(當然也可以遞減),同時每一列的元素也是嚴格單調遞增(同前面)。有了這種特點,使得它對於查詢某些元素,比堆的效能要好;而對於插入或者刪除元素,比bst更方便。
楊氏矩陣資料結構的特點有(如圖1):
1.是乙個m*n矩陣,並且對於同一行左邊的元素要小於(或大於)右邊的元素,同一列上面的元素要小於(或大於)下面的元素;
2.如過元素不夠組成乙個m*n矩陣,即矩陣有一定的空餘空間,那麼可以採用+∞(遞減的情況為-∞)填充。
圖1 楊氏矩陣
1 6 7 10
3 8 11 14
12 15 16 + ∞
13 18 +∞ + ∞
楊氏矩陣常用的操作:
1.對有空餘控制項的矩陣插入元素k,記為insert(y,k);
2.矩陣刪除位置為(m,n)處的元素,記為delete(y,(m,n));
3.從矩陣中查詢元素k,記為find(y,k);
4.對楊氏矩陣所有元素進行排序輸出;
5.其他相關的操作,類似於返回最大值max(y),或者min(y),以及除去最大最小值extract_max(y),extract_min(y)等等。
下面對這些操作進行詳細分析:
1.矩陣插入元素k,首先將元素k置於矩陣的空餘位置上。注意放置位置為先最左邊的最上面(或者是最上面的最左邊),因此可以將元素k放置在第四行第二列的位置上(或者是第三行第三列),假設k為2,那麼圖1變為:
圖2 楊氏矩陣
1 6 7 10
3 8 11 14
12 15 16 + ∞
13 18 2 + ∞
2作為新插入的元素,可以看到它打破了楊氏矩陣的特性,需要進行處理,保持楊氏矩陣的特點。從圖中看到2所在列的上面乙個元素為a[3][2]=15,所在行的前面元素為a[4][1]=20,並且a[4][1]>a[3][2]>2,所以2最好跟元素a[4][1]進行位置交換,如果跟所在列的位置a[3][2]進行交換的話,因為a[4][1]>a[3][2],列雖然保持了遞增的特點,但是又破壞了行遞增的特點,即還需要交換a[4][1]和a[3][2]的位置,所以應該讓2與本行的元素a[4][1]進行交換;反之,如果該行的前乙個元素要小於該列的上乙個元素那麼新插入的元素應該與該列的元素前乙個交換位置。這裡我們可以總結出插入元素步驟:
插入元素的初始位置為a[m][n],
如果a[m-1][n]>=a[m][n-1],並且a[m-1][n]>a[m][n],將a[m-1][n]與a[m][n]進行交換,對a[m-1][n]進行插入操作;
如果a[m-1][n]<=a[m][n-1],並且a[m][n-1]>a[m][n],將a[m][n-1]與a[m][n]進行交換,對a[m][n-1]進行插入操作;
如果a[m][n-1]圖3 因為18>16,所以2和18交換位置
1 6 7 10
3 8 11 14
12 15 16 + ∞
13 2 18 + ∞
圖4 因為15>13,所以2和15交換位置
1 6 7 10
3 8 11 14
12 2 16 + ∞
13 15 18 + ∞
圖5 因為12>8,所以2和12交換位置
1 6 7 10
3 8 11 14
2 12 16 + ∞
13 15 18 + ∞
圖6 因為3已經到了最左邊,所以2與上面的元素對比,3>2,交換位置,此時交換結束
1 6 7 10
2 8 11 14
3 12 16 + ∞
13 15 18 + ∞
小結:根據上面的操作可以看出,存在乙個遞迴過程,即不斷將插入元素網上或者往左移動,時間複雜度最差為o(m+n)。
2. 對於矩陣刪除位置為(m,n)處的元素,可以借鑑上面的插入操作,但是比較的方法簽好與上面相反。刪除元素是跟該元素下面的元素以及後面的元素進行比較,如果後面的元素小於下面的元素,那麼後面的元素與該元素交換,反之依然。具體的操作如下。
刪除元素的初始位置為a[m][n],
如果a[m+1][n]a[m][n+1],將a[m][n+1]與a[m][n]進行交換,對a[m][n+1]進行插入操作;
如果a[m][n+1]、a[m+1][n]元素存在,並且都為+∞,此時a[m][n]位置調整結束,將a[m][n]=+∞,刪除完成。
例如刪除(2,2)的元素8,如圖7:
圖7 楊氏矩陣刪除元素(2,2)
1 6 7 10
3 8 11 14
12 15 16 + ∞
13 18 +∞
3. 對於矩陣查詢元素k,由於楊氏矩陣並不是完全排序的,而只是區域性排好順序,即對每一行、每一列單獨來說是排好順序的,而對於不同的行,誰大誰小誰也摸不准。因此不能直接使用2叉排序樹的查詢演算法,而需要對2叉排序樹的查詢演算法進行修改。具體的操作如下。
檢視矩陣的左下角,如果左下角元素比k大,那麼就可以跳過左下角元素所在的行,往上繼續查詢;而如果左下角元素比k小,就可以跳過左下角元素所在列,往後面繼續查詢;(或者檢視矩陣的右上角,如果右上角元素比k大,那麼就可以跳過右上角元素所在的列,往前繼續查詢;而如果右上角元素比k小,就可以跳過右上角元素所在行,往下面繼續查詢;或者兩種步驟間歇性進行)
如果根據上面的兩步,以及搜尋完這個矩陣,還是沒有找到元素k,則返回布林值false,如果找到k值對應的元素,則返回true,並且儲存其對應的座標。
例如搜尋的元素8,如圖10:
圖10 楊氏矩陣刪除元素(2,2)
1 6 7 10
3 8 11 14
12 15 16 + ∞
13 18 +∞
4.對楊氏矩陣所有元素進行排序輸出,可以借鑑刪除元素操作來完成排序。我們根據楊氏矩陣元素的特徵可以看出:a[1][1]是矩陣中值最小的。所以依次刪除a[1][1],並輸出a[1][1],直到矩陣都為+∞,排序輸出結束。
楊氏矩陣查詢
題目為 在乙個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣的乙個二維陣列和乙個整數,判斷陣列中是否含有該整數。例如下面的二維陣列就是每行 每列都遞增排序,如果在這個陣列中查詢數字6,則返回true 如果查詢數字10,由於陣列不含有該數字...
楊氏矩陣查詢
方案一 時間複雜度o m n 原理 從右上角開始 左下角相同 如果arr i j t,就向左查詢,如果arr i j 2013.7.23 0423 function 楊氏矩陣查詢 在乙個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成乙個函式,輸入這樣的乙個...
楊氏矩陣查詢
題目描述 楊氏矩陣,即在乙個二維陣列中,每一行都按照從左到右嚴格遞增的順序排序,每一列都按照從上到下嚴格遞增的順序排序。請完成乙個函式,輸入這樣的乙個 n n的二維陣列和 m個整數,判斷陣列中是否含有上述 m個整數。你能解決這個問題嗎?輸入格式 可能有多個測試輸入,第一行給出總共的測試輸入的個數。對...