如果一个矩阵每一行每一列都严格单调递增,我们称该矩阵为杨氏矩阵(Young Tableau)。对于杨氏矩阵(a[m][ n]),通常会涉及两个问题:(1) 怎样在杨氏矩阵中查找某个元素X?(2) 怎样在杨氏矩阵找第k大的数?
2.堆查找方法
4.元素的插入
杨氏矩阵是一种非常巧妙的数据结构,它既可以用来当堆,又可以用来当做平衡树。
1.杨氏矩阵的查找
1.1先使用二分查找的方法
对于矩阵的查找并不是,真正的二分,因为矩阵会分成很多块的,而且对于杨氏矩阵来说,有很多块在a[mid][mid]
大于key时的分支,也可能在小于他的分支,这个好像会有两块公共的部分。下面给出的代码将这两个分治合并了,其实只要知道这个原理就行了。
/**
* @param a
* @param lowx
* @param highx
* @param lowy
* @param highy
* @param key
* @return
* 杨氏矩阵的二分查找算法
*/
public String youngSearch(int a[][],int lowx,int highx,int lowy,int highy,int key)
{
if(lowx<=highx&&highy>=lowy)
{
int midx=(lowx+highx)/2;
int midy=(lowy+highy)/2;
if(a[midx][midy]==key)
{
return midx+" "+midy;
}
else
{
String b=youngSearch(a, lowx, highx, lowy, midy-1, key);
String c=youngSearch(a, lowx, midx-1, midy, midy, key);
String d=youngSearch(a, midx+1, highx, lowy, midy, key);
String e=youngSearch(a,midx+1, highx, midy+1, highy, key);
String f=youngSearch(a, lowx, midx, midy+1, highy, key);
return b+" "+c+" "+d+" "+e+" "+f;
}
}
else
return null;
}
2.堆查找方法
因为杨氏矩阵非常类似堆,所以可以在最小得元素(左上角)开始,先判断此元素是否等于key,若不等于再分大于小于的情况,层层递归。此方法还是比较好的。
/**
* 杨氏矩阵查找算法2 采用堆查找算法,层层递归,从左上角往下查找
*
*/
public int[] youngSearch2(int a[][],int i,int j,int key)
{
if(a[i][j]==key)
return new int[]{i,j};
else if(a[i][j]>key)
{
return null;
}
else
{
if(i+1<a.length&&youngSearch2(a,i+1,j,key)!=null)
return youngSearch2(a,i+1,j,key);
if(j+1<a.length&&youngSearch2(a,i,j+1,key)!=null)
return youngSearch2(a,i,j+1,key);
return null;
}
}
2.杨氏矩阵的维护
杨氏矩阵的维护与堆很像,抓住每一个元素德 性质,a[i][j]位置的元素比a[i][j+1]和a[i+1][j]元素都小,抓住这一点进行维护。特别要注意是否越界,还有和他相邻的两个元素的下标表示。写代码时:就在这种小问题上出了错,特别纠结。
/**
*杨氏矩阵的维护算法
*/
public void younngMain(int a[][],int i,int j)
{
int right=j+1;
int down=i+1;
int minx,miny;
if(right<a.length&&a[i][right]<a[i][j])
{
minx=i;
miny=right;
}
else
{
minx=i;
miny=j;
}
if(down<a.length&&a[down][j]<a[minx][miny])
{
minx=down;
miny=j;
}
if(minx!=i||miny!=j)
{
int temp=a[minx][miny];
a[minx][miny]=a[i][j];
a[i][j]=temp;
younngMain(a, minx, miny);
}
}
3.建立杨氏矩阵
杨氏矩阵的建立就是从最后一个元素,依次对每一个元素维护,注意迭代从最后开始的话,就是i--。(这个脑残的问题是说给我自己的)这种小错误还是少错比较好。
/**
* 杨氏矩阵的建立算法
*/
public void buildYoung(int a[][])
{
for(int i=a.length-1;i>=0;i--)
for(int j=a.length-1;j>=0;j--)
{
younngMain(a, i, j);
}
}
4.元素的插入
同样是插入到最后一个位置,在进行减值操作,与堆一样,这里只是说明,不在代码表示。同样利用插入排序的思想对杨氏矩阵进行建立。