我认为二进制搜索需要一个连续的顺序。我不知道我是错还是对。有什么建议吗?
答案 0 :(得分:4)
你需要能够随机跳转(当前部分的中间),所以是的,需要随机访问。 (另外,要求是订购集合)。当然,假设您的结构是列表/数组。如果它是二叉树,您显然不需要随机访问。
答案 1 :(得分:4)
您无需随机访问即可进行二进制搜索。例如,二叉树支持二进制搜索,但不支持随机访问(至少在通常使用的术语中 - 对集合中任何元素的持续复杂访问)。
元素必须按某种顺序排列,以便与您正在搜索的键进行比较,这样您就可以确定如果键大于某个值X,那么它也大于其他所有值小于X的元素(或者你可以使用less而不是大于)。
虽然这种关系不必与数字排序相对应,但它必须能够根据与一个元素的比较来消除一定比例的元素(不仅仅是单个元素)。< / p>
答案 2 :(得分:2)
是。二进制搜索必须能够以随机(非顺序)方式访问数据结构的所有元素。
答案 3 :(得分:2)
是的, 需要随机访问。二进制搜索的整个想法是在每次迭代时将搜索空间细分为一半,并且为了确定新的搜索范围,使用索引。如果每次只是为了达到中间点而必须遍历搜索空间,那么你就是在否定算法的要点。
答案 4 :(得分:1)
二进制搜索是“跳入中间”。因此,有必要对数据进行某种顺序(这样中间定义良好),并且需要索引访问而不是迭代(为了能够跳转,否则O(log(CollectionSize))的运行时是不可能的。)
答案 5 :(得分:1)
它必须在搜索发生之前订购,它可以按升序或降序排序,这两个排序之间的区别是你应该在上半部分或下半部分看下一个并确定基于你的关键正在寻找
int binary_search(int A[], int key, int imin, int imax)
{
// test if array is empty
if (imax < imin):
// set is empty, so return value showing not found
return KEY_NOT_FOUND;
else
{
// calculate midpoint to cut set in half
int imid = (imin + imax) / 2;
// three-way comparison
if (A[imid] > key):
// key is in lower subset
return binary_search(A, key, imin, imid-1);
else if (A[imid] < key):
// key is in upper subset
return binary_search(A, key, imid+1, imax);
else:
// key has been found
return imid;
}
}
如果您的数组按降序翻转二进制运算符,则按升序运行 像这样
// three-way comparison
if (A[imid] < key):
// key is in lower subset
return binary_search(A, key, imin, imid-1);
else if (A[imid] > key):
// key is in upper subset
return binary_search(A, key, imid+1, imax);
else:
// key has been found
return imid;
}
答案 6 :(得分:0)
值得补充的是,Collections.binarySearch
方法不要求搜索列表是RandomAccess
的实例,其实现也会接受任何List
LinkedList
,如下所示:< / p>
public static <T>
int binarySearch(List<? extends Comparable<? super T>> list, T key) {
if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
return Collections.indexedBinarySearch(list, key);
else
return Collections.iteratorBinarySearch(list, key);
}
BINARYSEARCH_THRESHOLD等于5000(JDK 1.8)。当然,搜索和先前对LinkedList进行排序是非常低效的。程序员也习惯于在数组中考虑二进制搜索而不是链表,因此Collections.binarySearch
接受非RandomAccess集合的事实可能会令人惊讶。