简体   繁体   English

排序二维数组的二进制搜索

[英]Binary Search of sorted 2d array

I have a program that searches a 2d array using a binary search. 我有一个使用二进制搜索来搜索2d数组的程序。 In this case I am using the matrix below and searching for the integers 4,12,110,5,111. 在这种情况下,我使用下面的矩阵并搜索整数4,12,110,5,111。 The program finds all of them except for 110 and 111 why is this? 程序会找到除110和111以外的所有字符,为什么?

       {1,3,7,8,8,9,12},
       {2,4,8,9,10,30,38},
       {4,5,10,20,29,50,60},
       {8,10,11,30,50,60,61},
       {11,12,40,80,90,100,111},
       {13,15,50,100,110,112,120},
       {22,27,61,112,119,138,153},


public static boolean searchMatrix(int[][] matrix, int p,int n) {  

int low = 0, high = n-1 ;  
while (low < high) {  
 int mid = (low + high) / 2;  
 if (p == matrix[mid][0])return true;  
 else if (p < matrix[mid][0]) high = mid - 1;  
 else if (p < matrix[mid+1][0]) { low = mid; break; }  
 else low = mid + 1;  
}  


int row = low;  
low = 0; high = matrix[row].length - 1;  
while (low <= high) {  
 int mid = (low + high) / 2;  
 if (p == matrix[row][mid]) return true;  
 else if (p < matrix[row][mid]) high = mid - 1;  
 else low = mid + 1;  
}  

return false;  
}  

I would rather say it's more or less a surprise that your algorithm does find 4, 5, and 12 in the first place. 我宁愿说您的算法确实找到4、5和12多少有点令人惊讶。 The reason for that is that 4 occurs in the first position of a row and 5 and 12 satisfy the condition that they are less than the first element in the next row. 这是因为在一行的第一位置出现了4,而5和12满足的条件是它们小于下一行的第一个元素。 Only due to that fact are they discovered in the second half of your algorithm. 仅由于这个事实,它们才在算法的后半部分被发现。 The algorithm is a bit hard to read and I did not evaluate the +/-1 magic, but it seems the algorithm expects the 110 and 111 to occur actually in the last row (since both 110 and 111 are greater than 22) where they are not. 该算法有点难以理解,我没有评估+/- 1的魔力,但似乎该算法希望110和111实际上出现在最后一行(因为110和111都大于22)。不是。

If I get you right, your approach is flawed in that it is actually impossible, by looking at a single number, to tell what row it will occur in, which is what your first tries to achieve. 如果我理解正确,那么您的方法就有缺陷,因为实际上不可能通过查看单个数字来判断行将出现在哪一行,这是您第一个尝试实现的目标。 So any two-phase algorithm that first picks a row and then searches a column must fail. 因此,任何先选择行然后搜索列的两阶段算法都必须失败。

With the few constraints you have on your matrix (each row and each column is sorted), it does not seem like binary search will work at all: Even if your bounds low and high would be 2D points it would not help a lot. 有了你有你的矩阵(每行和每列进行排序)的约束很少,它似乎并不像二进制搜索将在所有的工作:即使你的界限lowhigh将2D点不会有很大的帮助。 Consider any element of the matrix that is greater than your search point. 考虑矩阵中大于搜索点的任何元素。 Then all you can say is that your search point is not below and right of that element (whereas what you were hoping to be able to conclude was that it was left and above, but that is not necessarily true - it can be above and right or left and below), so you are only cutting off only a too small part of the search space. 然后,您只能说搜索点不在该元素的下方右侧(而您希望能够得出的结论是,该搜索点位于左侧和上方,但这不一定是正确的-它可以位于上方和右侧或左侧和下方),因此您只切断了搜索空间的一小部分。

Your issue is that you are making the false assumption that you can first lock down the row of your search value, and then easily do binary search on that row. 您的问题是您做出了错误的假设,即您可以首先锁定搜索值的行,然后轻松地对该行进行二进制搜索。 That's not the case at all. 根本不是这样。

For 110 and 111, the first element of each row is always less than your search value, and your algorithm comes to the false conclusion that that this means that your row must be the array with index 6 after the first loop. 对于110和111,每行的第一个元素始终小于您的搜索值,并且您的算法得出的错误结论是,这意味着您的行必须是第一个循环之后具有索引6的数组。 This is simply not true. 这是不正确的。

The reason it works for small numbers is because your algorithm is just lucky enough to lock down the right row in the first loop... 它适用于小数的原因是因为您的算法足够幸运,可以在第一个循环中锁定右行...

One correct algorithm to quickly search on a 2d matrix where every row and column is sorted in ascending order is as follows: 一种快速搜索二维矩阵的正确算法,其中每个行和列都按升序排序,如下所示:

1) Start with top right element 2) Loop: compare this element e with x ….i) if they are equal then return its position …ii) e < x then move it to down (if out of bound of matrix then break return false) ..iii) e > x then move it to left (if out of bound of matrix then break return false) 3) repeat the i), ii) and iii) till you find element or returned false 1)从右上角的元素开始2)循环:将该元素e与x….i)比较,如果相等,则返回其位置…ii)e <x然后向下移动(如果超出矩阵范围,则中断return false)..iii)e> x,然后将其向左移动(如果超出矩阵范围,则返回false)3)重复i),ii)和iii)直到找到元素或返回false

I found this algorithm here: http://www.geeksforgeeks.org/search-in-row-wise-and-column-wise-sorted-matrix/ 我在这里找到了该算法: http : //www.geeksforgeeks.org/search-in-row-wise-and-column-wise-sorted-matrix/

It's O(n) for an nxn matrix. 对于nxn矩阵为O(n)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM