为什么binarysearch方法将负返回值减少1

时间:2019-09-12 16:49:06

标签: java arrays binary-search

谈论此在数组中定义的方法:

public static int binarySearch(int[] a, int key)

在数组中找不到匹配项的情况下,为什么不能返回(-(insertion point) - 1)而不是-(insertion point),我无法理解。

https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#binarySearch(int[],%20int)

是否可能是Math.abs((-(insertion point) - 1))等于数组大小的原因?

如果您想知道为什么我要问这个,我发现要找到插入点,我必须进行减法运算。

int returnedVal = Arrays.binarySearch(arr, needle);
if (returnedVal < 0) 
     insertionPoint = Math.abs(returnedVal) - 1; 

2 个答案:

答案 0 :(得分:3)

因为0是合法的插入点,但是您不能只返回0,因为那将意味着在索引0处找到了键。

编辑:请注意,选择减1而不是其他数字并非是任意的。 -a - 1等于~a(a的按位取反),该函数对所有正(和负)整数都是双射的,因为它只是翻转位并使用整个Integer范围:~Integer.MIN_VALUE == Integer.MAX_VALUE~(-1) == 0。另请注意,~(~a) == a

您可以通过执行~returnedVal找到插入点。 Java中的整数始终使用二进制补码,因此等效性有效。

使用任何大于1的子交易,都会导致Integer.MAX_VALUE附近的最高索引出现整数下溢。有关〜运算符的更多信息,请参见Explanation of Bitwise NOT Operator

答案 1 :(得分:2)

否,插入点不一定等于数组的大小;从理论上讲,可以将有问题的项目插入数组中的任何位置。

有可能找不到该项目,但也可能少于(已排序)数组中的所有项目。这将意味着插入点为0。但是使用-(insertion point)意味着将返回0。这意味着该项目是在位置0上被找到的。他们减去一个以避免发生这种冲突,因此少于所有其他项的项将返回-1

当然,如果您确实想将一项插入数组,则必须添加一个,然后取反以找到插入位置。但是考虑到您必须移动数组的内容以为数组中的新项目腾出空间,可以做一些额外的数学运算可以忽略不计。

二进制搜索过程完成查找插入点的工作。如果它只是返回了-1,则必须重做搜索以找到插入点。该方法在返回“未找到”方案时为您提供了一些额外的信息,可以在需要将项目插入数组时使用。只是需要避免0表示“在第一个位置找到”和“未找到,但在开头插入”的情况。