[算法學習]楊氏矩陣

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章