谈论此在数组中定义的方法:
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;
答案 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表示“在第一个位置找到”和“未找到,但在开头插入”的情况。