我想过这个问题,去年...所以,我会选用这种方法:
考虑你的二维数组表示在平面上的点。例如,你的元素A [i] [j]表示一个x = i和y = j的点。在飞机上使用二进制搜索我有点所有使用这个情况分:
点P1 < P2当且仅当:
- (x坐标P1)的<(P2的x坐标)
- (x坐标p1的)=(P2的x坐标)和(P1的y坐标)<(p2的Y坐标)
Othwerwise P1> P2 =。
现在,如果我们查看我们的2D数组,第二行中的元素应该大于第一行中的元素。在通常排序的相同行元素中(根据其列号)。
换句话说:
- A [i] [j]> A [k]的[j]的当且仅当(ⅰ> K)。 (在不同的行和列中)
- A [i] [j]> A [i] [k]当且仅当(j> k)。 (在同一行和不同列中)
考虑你的数组有N行和M列。
for i:=0 to N-1 do
for j:=0 to M-1 do
T[i*N + j]:= A[i][j];
现在你有一维数组: - 现在,你应该(即暂时)使用此公式(临时阵列T)将您的二维数组一维数组。以通常的方式分类。现在您可以使用简单的二进制搜索算法进行搜索。
或者您可以使用此公式将您的排序阵列回二维数组:
for i:=0 to N*M-1 do
A[i div N][i - (i div N)*N]:= T[i];
并使用两个二进制搜索:
一个被搜索的x坐标(在我们的意思行)另一个由y坐标(在我们的意义上的列)为同一行中的元素。
换句话说,当你计算mid = mid + (max - min) div 2
,你可以比较元素A [MID] [0]与您的关键元素(在你的代码有X名称),当你发现你的牙齿列,你可以调用此行中的另一个二分搜索(A [mid]中的二分搜索)。
复杂度的两种方法:
- 用于trasformed阵列简单二进制搜索:用于2D阵列的两个二进制搜索日志(N * M)
- :日志(N)为外搜索(按行) + log(M)用于内部搜索(按列)。
使用对数函数的性质,我们可以简化最后一个表达式:日志(N)+日志(M)=日志(N * M)。
所以,我们证明,这两种方法具有相同的复杂性,并不重要,哪一个使用。但是,如果对你不难,我建议你简单地将你的数组转换为1-D,并使用简单的二进制搜索(它非常简单,易于调试和检查)。
有什么特别的你想要实现? – NPE 2010-12-13 14:53:24
我的第一个建议是让你的一维算法得到解决。可能有 几个界限问题。考虑一个大小为1的数组。这里'min = 1'和'max = 1'。 然后'mid:= min +(max-min)div 2'产生'mid = 0'(假设整数运算)。 然后谁知道'A [mid]'等于什么(给定'A'被索引为:1..N)。 – NealB 2010-12-13 16:23:26
@NealB这只是维基百科中的代码...它并不重要,它只是为了演示.. – Betamoo 2010-12-14 12:45:41