[英]How do i find the index of the number in a divide and conquer binary search?
I can use the divide and conquer binary search to find the number i want but how can i find the index of the number in the original array without using for loop and indexOf? 我可以使用分治法二分查找法找到我想要的数字,但是如何在不使用for循环和indexOf的情况下找到原始数组中数字的索引?
function search(array, value) {
var midpoint = Math.floor(array.length / 2)
if (value > array[midpoint]) {
var slicedArray = array.slice(midpoint)
} else {
var slicedArray = array.slice(0,midpoint)
}
return slicedArray[Math.floor((slicedArray.length/2))] === value ? value : search(slicedArray, value)
}
console.log(search([1,3,16,22,31,33,34], 34))
You can and should condense this code substantially, but I've left it in a longer form to better illustrate the concepts. 您可以并且应该实质上压缩该代码,但为了使这些概念更好地说明,我将其保留了较长的形式。
function search(array, value) {
if (array.length == 0)
return NaN;
var midpoint = Math.floor(array.length / 2);
if (array[midpoint] === value)
return midpoint;
if (array[midpoint] < value)
return search(array.slice(midpoint+1),value) + midpoint + 1;
if (array[midpoint] > value)
return search(array.slice(0,midpoint),value);
}
When you write a recursive function, the first two questions you should always ask yourself are "How do I know I'm done?" 在编写递归函数时,您应该经常问自己的前两个问题是:“我怎么知道我已经完成了?” and "No really, is there any way this could fail to reach a completion condition?"
和“不,这是否有可能无法达到完成条件?”
You want to make certain you have covered every possible state. 您想确定已覆盖所有可能的状态。 In this case, there are four:
在这种情况下,有四个:
Using NaN
as the 'search failed' return value is convenient because it avoids needing null-checking conditional logic around returning the value from recursion back up the chain; 将
NaN
用作“搜索失败”的返回值很方便,因为它避免了在递归返回链中返回值时需要进行空检查条件逻辑。 NaN
plus a number equals NaN
. NaN
加一个数字等于NaN
。
You don't need to know and shouldn't try to calculate the index of the search value in the original array at the moment you find it, several recursive calls later. 您无需知道,也不应尝试在找到原始数组时计算搜索值的索引,以后将进行几次递归调用。 It's the calling instance's job to combine what it knows (its own midpoint) with the result of the recursion and return a useful value back up the chain.
调用实例的工作是将其知道的内容(自己的中点)与递归结果相结合,并在链中返回有用的值。 In fact, no particular call to this function should 'know' whether it was the original call or a recursion.
实际上,对此函数的任何特定调用都不应该“知道”它是原始调用还是递归。 If you ever find yourself NEEDING to know the answer to that question, it's a warning flag that you should re-examine your logic.
如果您发现自己想知道该问题的答案,那是一个警告信号,您应该重新检查您的逻辑。
You can have a wrapper function _binarySearch
to do the actual binary search, along with taking two additional parameters l, r
, whereas you can call search with just two parameters array, value
您可以使用包装器函数
_binarySearch
进行实际的二进制搜索,同时使用两个附加参数l, r
,而您可以仅使用两个参数array, value
调用search
function _binarySearch(array, value, l, r) {
if (l > r) return -1;
var midPoint = Math.floor((l + r) / 2);
if (value == array[midPoint])
return midPoint;
else if (value > array[midPoint])
return _binarySearch(array, value, midPoint + 1, r);
else
return _binarySearch(array, value, l, midPoint - 1);
}
function search(array, value) {
return _binarySearch(array, value, 0, array.length);
}
If you want to know the first occurrence of an element, the worst case time complexity of the algorithm is not O(log n) anymore, it degenerates to O(n) . 如果您想知道元素的首次出现,则算法的最坏情况下的时间复杂度不再是O(log n) ,它会退化为O(n) 。
This modification becomes necessary 进行此修改是必要的
if (value == array[midPoint]) {
while(midPoint > -1 && array[midPoint] == value)
--midPoint;
return midPoint + 1;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.