杨氏矩阵数据结构的特点有(如图1):
1.是一个M*N矩阵,并且对于同一行左边的元素要小于(或大于)右边的元素,同一列上面的元素要小于(或大于)下面的元素;
2.如过元素不够组成一个M*N矩阵,即矩阵有一定的空余空间,那么可以采用+∞(递减的情况为-∞)填充。
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变为:
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],
根据上面的操作具体的步骤:
1 | 6 | 7 | 10 |
3 | 8 | 11 | 14 |
12 | 15 | 16 | + ∞ |
13 | 2 | 18 | + ∞ |
1 | 6 | 7 | 10 |
3 | 8 | 11 | 14 |
12 | 2 | 16 | + ∞ |
13 | 15 | 18 | + ∞ |
1 | 6 | 7 | 10 |
3 | 8 | 11 | 14 |
2 | 12 | 16 | + ∞ |
13 | 15 | 18 | + ∞ |
1 | 6 | 7 | 10 |
2 | 8 | 11 | 14 |
3 | 12 | 16 | + ∞ |
13 | 15 | 18 | + ∞ |
2. 对于矩阵删除位置为(m,n)处的元素,可以借鉴上面的插入操作,但是比较的方法签好与上面相反。删除元素是跟该元素下面的元素以及后面的元素进行比较,如果后面的元素小于下面的元素,那么后面的元素与该元素交换,反之依然。具体的操作如下。
删除元素的初始位置为A[m][n],
例如删除(2,2)的元素8,如图7:
1 | 6 | 7 | 10 |
3 | 8 | 11 | 14 |
12 | 15 | 16 | + ∞ |
13 | 18 | +∞ | + ∞ |
1 | 6 | 7 | 10 |
3 | 11 | 8 | 14 |
12 | 15 | 16 | + ∞ |
13 | 18 | +∞ | + ∞ |
1 | 6 | 7 | 10 |
3 | 11 | 14 | 8 |
12 | 15 | 16 | + ∞ |
13 | 18 | +∞ | + ∞ |
小结:根据上面的操作可以看出,存在一个递归过程,即不断将删除元素往下或者往后移动,时间复杂度最差为o(M+N)。
3. 对于矩阵查找元素k,由于杨氏矩阵并不是完全排序的,而只是局部排好顺序,即对每一行、每一列单独来说是排好顺序的,而对于不同的行,谁大谁小谁也摸不准。因此不能直接使用2叉排序树的查找算法,而需要对2叉排序树的查找算法进行修改。具体的操作如下。
例如搜索的元素8,如图10:
1 | 6 | 7 | 10 |
3 | 8 | 11 | 14 |
12 | 15 | 16 | + ∞ |
13 | 18 | +∞ | + ∞ |
1 | 6 | 7 | 10 |
3 | 8 | 11 | 14 |
12 | 15 | 16 | + ∞ |
1 | 6 | 7 | 10 |
3 | 8 | 11 | 14 |
6 | 7 | 10 |
8 | 11 | 14 |
小结:根据上面的操作可以看出,存在一个循环(递归)过程,即不断往上或者往前移动,时间复杂度最差为o(M+N)。
4.对杨氏矩阵所有元素进行排序输出,可以借鉴删除元素操作来完成排序。我们根据杨氏矩阵元素的特征可以看出:A[1][1]是矩阵中值最小的。所以依次删除A[1][1],并输出A[1][1],直到矩阵都为+∞,排序输出结束。
5.返回最大值MAX(Y),或者MIN(Y),以及除去最大最小值EXTRACT_MAX(Y),EXTRACT_MIN(Y)这些操作都是前面三种基本操作的不同形式或者不同的组合,这里不再赘述了。