[算法学习]杨氏矩阵

1.定义

   杨氏矩阵中,每行元素是递增的,每列元素也是递增的。

2.杨氏矩阵中查找

   思想:从矩阵的右上角(或者左下角)开始查找num,如果a[i][j]<num,则比较a[i][j+1]与num之间的关系;如果a[i][j]>num,则比较a[i-1][j]与num之间的关系。当a[i][j]等于num,或者i、j至少有一个超出矩阵范围,则结束查找。
   查找流程图如下所示:
  
  算法复杂度:o(n+m)

3、按从小到大顺序输出杨氏矩阵中各数

   思想:类似于堆排序。a[0][0]必然是杨氏矩阵中最小的那个数,取出这个数,并用a[N-1][M-1]这个数替换。此时该矩阵已不满足杨氏矩阵条件,需要对其进行调整。调整方法
a[i][j]与a[i][j+1]进行比较,得出a[i][j]与a[i][j+1]大小关系,如果a[i][j]<a[i][j+1],则a[i][j]与a[i][j+1]互换。然后再比较a[i][j]与a[i+1][j]的大小关系,如果a[i][j]<a[i+1][j],则互换。然后递归调整。当a[i][j]>a[i][j+1]&&a[i][j]>a[i+1][j]时,调整完毕。
  伪代码
   
YOUNG-EXTRACT-MIN(A)
min←A[1,1]
A[1,1]←A[m,n]
YOUNG-MIN-HEAPIFY(A, 1, 1)
return min
YOUNG-MIN-HEAPIFY(A, i, j)
if j<n and A[i,j]>A[i,j+1]
   then (min_i, min_j) = (i, j+1)
   else (min_i, min_j) = (i, j)
if i<m and A[min_i, min_j] > A[i+1,j]
   then (min_i, min_j) = (i+1, j)
   if min_i≠i or min_j≠j
   then exchange A[i,j]↔A[min_i,min_j]
        YOUNG-MIN-HEAPIFY(A,min_i,min_j

4、代码实现

#include<iostream>
using namespace std;
#define N 4
#define M 4
int findNum(int a[][M],int num);
void young_extract_min(int a[][M]);
void young_min_heapy(int a[][M],int row,int col);
int main()
{
	int a[N][M]={{1,2,3,4},{5,6,7,8},{9,10,11,-9999},{13,14,15,-9999}};
	int ret,num;
	cin>>num;
	ret=findNum(a,num);
	if(ret==-1)
		cout<<num<<"没有找到"<<endl;
	else
		cout<<num<<"存在杨氏矩阵中"<<endl;
	young_extract_min(a);
	return 0;
}
/*
*功能:查找某个数是否存在于杨氏矩阵,从右上角开始比较,如果矩阵某一位置的数大于查找数,则列序减一,反之则行序加一
*/
int findNum(int a[][M],int num)
{
	int ret=-1;
	int i=0,j=M-1;
	while(1)
	{
		if(i>=0&&i<N&&j>=0&&j<M)
		{
			if(a[i][j]==num)
			{
				ret=i*M+j;
				break;
			}else
				if(a[i][j]<num)
				{
					++i;
				}else
				{
					--j;
				}
		}else
			break;

	}
	return ret;
}
/*
*功能:按从小到大顺序输出杨氏矩阵中的数.
*/
void young_extract_min(int a[][M])
{
	int min;
	for(int i=N-1;i>=0;i--)
		for(int j=M-1;j>=0;j--)
		{
			min=a[0][0];
			if(min!=-9999)
			{
				cout<<min<<" ";
			}
			a[0][0]=a[i][j];
			a[i][j]=-9999;
			young_min_heapy(a,0,0);
		}

}
/*
*功能:调整数组,使其满足杨氏矩阵条件.调整类似于堆调整
*/
void young_min_heapy(int a[][M],int row,int col)
{
	int min_i=row;
	int min_j=col;
	if(min_j<M-1&&a[row][col+1]!=-9999&&a[min_i][min_j]>a[row][col+1])
	{
		min_i=row;
		min_j=col+1;
	}
	if(min_i<N-1&&a[row+1][col]!=-9999&&a[min_i][min_j]>a[row+1][col])
	{
		min_i=row+1;
		min_j=col;
	}
	if(min_i!=row || min_j!=col)
	{
		int tmp=a[min_i][min_j];
		a[min_i][min_j]=a[row][col];
		a[row][col]=tmp;
		young_min_heapy(a,min_i,min_j);
	}
}
参考:http://blog.csdn.net/zhanglei8893/article/details/6234564
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章