我对在二进制搜索中何时使用=
的情况感到很困惑。例如,这是我在wiki中找到的,它在(imin <= imax)
int binary_search(int A[], int key, int imin, int imax)
{
// continue searching while [imin,imax] is not empty
while (imin <= imax)
{
int imid = midpoint(imin, imax);
if (A[imid] == key)
return imid;
else if (A[imid] < key)
imin = imid + 1;
else
imax = imid - 1;
}
return KEY_NOT_FOUND;
}
但是,我也发现了很多使用类似
的代码while (imin < imax)
我的问题是:使用=
的关注点是什么?有什么理由吗?
非常感谢!
答案 0 :(得分:2)
请注意wiki上的这两种算法:
迭代二分查找:
int binary_search(int A[], int key, int imin, int imax)
{
// continue searching while [imin,imax] is not empty
while (imin <= imax)
{
// calculate the midpoint for roughly equal partition
int imid = midpoint(imin, imax);
if (A[imid] == key)
// key found at index imid
return imid;
// determine which subarray to search
else if (A[imid] < key)
// change min index to search upper subarray
imin = imid + 1;
else
// change max index to search lower subarray
imax = imid - 1;
}
// key was not found
return KEY_NOT_FOUND;
}
使用延迟检测相等性的迭代二进制搜索:
int binary_search(int A[], int key, int imin, int imax)
{
// continually narrow search until just one element remains
while (imin < imax)
{
int imid = midpoint(imin, imax);
// code must guarantee the interval is reduced at each iteration
assert(imid < imax);
// note: 0 <= imin < imax implies imid will always be less than imax
// reduce the search
if (A[imid] < key)
imin = imid + 1;
else
imax = imid;
}
// At exit of while:
// if A[] is empty, then imax < imin
// otherwise imax == imin
// deferred test for equality
if ((imax == imin) && (A[imin] == key))
return imin;
else
return KEY_NOT_FOUND;
}
在imin < imax
,imin == imax
和imin > imax
时,您需要考虑三种情况。第一个算法处理while循环中的小于和等于,而在第二个算法中,相等的情况被推迟到if语句。正如维基所说:
迭代和递归版本基于密钥比较采用三个路径:一个路径用于小于,一个路径用于大于,一个路径用于相等。 (有两个条件分支。)仅当记录最终匹配时才采用相等的路径,因此很少采用。对于算法的相等版本,该分支路径可以在延迟测试中移动到搜索循环之外。
延迟检测方法放弃了在发现匹配时提前终止的可能性,因此搜索将花费大约log2(N)次迭代。平均而言,成功的提前终止搜索不会节省很多次迭代。对于功率为2的大型阵列,节省大约两次迭代。一半时间,找到一个匹配,剩下一个迭代;剩下两次迭代的时间的四分之一,三次迭代的八分之一,等等。无限级数和为2。
延迟检测算法的优点是,如果密钥不是唯一的,则返回元素具有搜索关键字的区域的最小索引(起始索引)。提前终止版本将返回它找到的第一个匹配项,并且该匹配项可能位于相同键区域中的任何位置。
因此,在while循环或<=
中使用<
取决于您对实现的选择。