分析与解答:
a)遵循每一行的数据都从左到右排序,每一列的数据都从上到下排序,可以很容易写出一个可能的Young氏矩阵
2 3 4 5
6 8 9 12
14 ∞ ∞ ∞
∞ ∞ ∞ ∞
b)Y[1,1]是Young氏矩阵中最小的元素,如果它为∞,说明矩阵中每个元素的值均不小于∞,即每个元素均是∞,所以Y为空;Y[m,n]是Young氏矩阵中最大的元素,如果Y[m,n]<∞,说明矩阵中每个元素均小于∞,即Y是满的
c)采用类似堆中提取最小元素的方法:将Young氏矩阵中最末的元素和第一个元素交换,然后类似MAX-HEAPIFY的方法调整第一个元素,整个过程如下:
void YOUNG_MIN_HEAPIFY(int a[][n],int i,int j) { int min_i,min_j; if(j<n&&a[i][j]>a[i][j+1]) { min_i=i; min_j=j+1; } else { min_i=i; min_j=j; } if(i<m&&a[min_i][min_j]>a[i+1][j]) { min_i=i+1; min_j=j; } if(min_i!=i||min_j!=j) YOUNG_MIN_HEAPIFY(a,min_i,min_j); } int EXTRACT_MIN(int a[][n]) { int min=a[1][1]; a[1][1]=a[m][n]; YOUNG_MIN_HEAPIFY(a,1,1); return min; }
而YOUNG-MIN-HEPIFY是一个递归过程。YOUNG-MIN-HEAPIFY(A, m, n)会和它紧邻的结点比较,要么调用YOUNG-MIN-HEAPIFY(A, m, n-1),要么调用YOUNG-MIN-HEAPIFY(A, m-1, n)。若令p=m+n,则有:
T(p)= T(p-1)+O(1)
则总的运行时间为O(p),即为O(m+n)
(4)采用类似堆中增加元素的方法,先将∞放在Young矩阵的末尾,然后采用类似INCREASE-KEY的方法,向上调整
void YOUNG_DECREASE_KEY(int a[][n],int i,int j,int key) { int max_i,max_j; if(j>1&&a[i][j]<a[i][j-1]) { max_i=i; max_j=j-1; } else { max_i=i; max_j=j; } if(i>1&&a[i-1][j]>a[max_i][max_j]) { max_i=i-1; max_j=j; } if(max_i!=i||max_j!=j) { int temp=a[i][j]; a[i][j]=a[max_i][max_j]; a[max_i][max_j]=temp; } } void YOUNG_INSERT(int a[][n],int key) { if(a[m][n]<INT_MAX) cout<<"矩阵已满"<<endl; a[m][n]=INT_MAX; YOUNG_DECREASE_KEY(a,m,n,key); }
(5)每次与最右上角的元素X相比:如果等于X,则找到了;如果小于X,则去掉最上面一行;如果大于X,则去掉最右边一行。
每次比较去掉一行或一列,则该算法的运行时间为O(m+n)
void YOUNG_SEARCH(int a[][n],int i,int j,int key) { if(i>m||j<0) cout<<"can not find"<<endl; if(a[i][j]==key) cout<<i<<" "<<j<<endl; else if(a[i][j]<key) YOUNG_SEARCH(a,i+1,j,key); else YOUNG_SEARCH(a,i,j-1,key); }