杨氏矩阵

如果一个矩阵每一行每一列都严格单调递增,我们称该矩阵为杨氏矩阵(Young Tableau)。对于杨氏矩阵(a[m][ n]),通常会涉及两个问题:(1) 怎样在杨氏矩阵中查找某个元素X?(2) 怎样在杨氏矩阵找第k大的数?

杨氏矩阵是一种非常巧妙的数据结构,它既可以用来当堆,又可以用来当做平衡树。

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.元素的插入

同样是插入到最后一个位置,在进行减值操作,与堆一样,这里只是说明,不在代码表示。同样利用插入排序的思想对杨氏矩阵进行建立。


    


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值