有序矩阵的快速查找
1. 问题描述及分析
1、一个有序的数组,如何快速的查找一个数?
回答:二分查找
2、那么如果是二维数组,从左到右从上到下都是升序的,又该如何快速查找呢?
回答:
(1)解法一:逐个元素对比;
(2)解法二:逐行二分或逐列二分;
(3)解法三:找规律
下面根据问题描述,来分析规律:
每行每列都升序,则:
根据上面的规律,可以二分行或列,通过判断数据大小,删除多行或多列,把大问题化解为小问题。根据上面找出的规律,有很多的方式都可以缩小问题规模,那从哪个点开始判断呢:
所以从右上或者左下都可以。
2. 算法建模实现
根据上面的分析,我们选取右上点为基准点,先通过按行二分,缩小列,再通过按列二分,缩小行,来实现快速查找:
- 代码实现如下:
/**选取右上元素为基准点,通过二分缩小法快速查找位置:
* 先按行二分快速定位
* 再按列二分快速定位*/
public boolean dichotomySearch(int[][] matrix,int x){
boolean isExist = false;
if(matrix == null || matrix.length == 0){
return isExist;
}
//x < 最小元素 或 x > 最大元素
if(x < matrix[0][0] || x > matrix[matrix.length-1][matrix[0].length-1]){
System.out.println(x+"不在有序矩阵中");
return isExist;
}
//x 在矩阵元素范围内,查找具体行列位置
int up_row = 0,right_col = matrix[0].length-1;
while(!(up_row == matrix.length || right_col < 0)){
right_col = searchColumn(matrix, x, up_row);
if(right_col < 0){
continue;
}
up_row = searchRow(matrix, x, right_col);
if(up_row == matrix[0].length){
continue;
}
if(matrix[up_row][right_col] == x){
isExist = true;
break;
}
}
if(isExist){
System.out.println(x+"在矩阵的第"+(up_row+1)+"行,第"+(right_col+1)+"列");
}else{
System.out.println("矩阵中没有值为"+x+"的元素");
}
return isExist;
}
/**按行二分,缩小列*/
public int searchColumn(int[][] matrix, int x,int row) {
int i = 0,j = matrix[0].length-1,mid;
while(i < j){
mid = (i+j)/2;
if(x < matrix[row][mid]){
j = mid - 1;
}else if(x > matrix[row][mid]){
i = mid + 1;
}else{
i = j = mid;
}
}
if(matrix[row][i] > x){
--i;
}
return i;
}
/**按列二分,缩小行*/
public int searchRow(int[][] matrix, int x,int col) {
int i = 0,j = matrix.length-1,mid;
while(i < j){
mid = (i+j)/2;
if(x < matrix[mid][col]){
j = mid - 1;
}else if(x > matrix[mid][col]){
i = mid + 1;
}else{
i = j = mid;
}
}
if(matrix[i][col] > x){
--i;
}
return i;
}
- 测试:
这里有序矩阵的生成,可参考:矩阵排序-行列升\降序 -java.
public static void main(String[] args) {
MatrixSorting t = new MatrixSorting();
//生成有序矩阵
int[][] matrix = t.createSortMatrix(4,5,0,100,true);
System.out.println("生成的有序矩阵打印如下:");
t.printMatrix(matrix);
//快速查找
QuickLookupOfMatrix s = new QuickLookupOfMatrix();
System.out.println(s.dichotomySearch(matrix, matrix[2][3]));
}
测试结果如下:
上一篇:矩阵排序-行列升\降序 -java.