[英]Binary search function not working
我是Java的新手,刚刚开始学习一些简单的数据结构和算法。 我一直在尝试实现二进制搜索功能,但是我一直收到堆栈溢出错误,而且我不知道它从哪里来。
public class BinarySearch {
public static void main (String[]args){
BinarySearch bs = new BinarySearch();
int array [] = {1, 8, 6, 91, 52, 74, 5, 9};
int length = array.length;
bs.sort(array, 0, length-1);
bs.print(array);
System.out.println();
System.out.println(bs.binarySearch(array, 0, length-1, 5));
}
public int binarySearch(int array [], int low, int high, int desired){
int pivot = array[(low+high)/2];
if(desired<pivot){
binarySearch(array,low,pivot, desired);
}else if(desired>pivot){
binarySearch(array, pivot+1, high, desired);
}else {
return (low+high)/2;
}
// if element not present in array
return -1;
}
您的代码有几个问题。
您不会返回递归调用的结果。 添加return
。
if(desired<pivot){ return binarySearch(...); }else if(desired>pivot){ return binarySearch(...); }
不要将要检查的索引与要检查的枢轴值混合在一起。 计算索引并单独使用。 另外,当重复出现低值时,请使用index - 1
代替index
作为high
值,以免将来考虑使用当前索引。
int index = (low+high)/2; int pivot = array[index]; if(desired<pivot){ return binarySearch(array,low,index - 1, desired); }else if(desired>pivot){ return binarySearch(array, index+1, high, desired); }else { return index; }
如果您的低价值大于高价值,那么找不到价值。 这是您的基本情况,不会在底部返回-1
(现在无论如何都是无法访问的代码,因为上述逻辑的每个分支都已经返回了一个值)。 if
将其置于您当前的上方。
int index = (low+high)/2; int pivot = array[index]; if (low > high) return -1; if ...
假设sort
工作正常,以上更改应正确返回元素的索引;如果未找到,则返回-1
。
当我运行它时,我得到一个indexoutofboundsexception
因为在这些行中:
int pivot = array[(low+high)/2];
if(desired<pivot){
binarySearch(array,low,pivot, desired);
}
您将pivot
作为高点传递,可以是array
任何数字。 在此摘录的第一行中,您将索引称为high + low
,该索引可以是array
任何数字加上您最初传递给low
任何值。 因此,在此示例中,您可以调用array
的0 + 92
索引。
关于StackOverflow
它在这一行:
if(desired<pivot){
binarySearch(array,low,pivot, desired);
}
在这里,您在递归调用中传递了完全相同的参数,因此,如果它进入if
循环的此分支,它将继续调用递归调用,直到它们中的太多进入堆栈并且出现堆栈溢出错误为止
当阵列本身已经排序(按顺序)BinarySearch的使用,这是二分查找的基础,你已经做了排序的一部分。
但是,您的解决方案中存在两个明显的问题:
pivot
,您在此处使用元素作为索引 ; if (desired < pivot)
;包括应该忽略的mid
; 此外,您应该尝试使用low + (high-low) / 2
来获取中间索引(当数组的大小足够大时low + high
会炸毁int
),然后获取pivot = array[mid]
为了避免整数溢出,这也是获取中间索引的一种更好的做法。
public class BinarySearchBasic {
public static void main(String[] args) {
BinarySearchBasic bs = new BinarySearchBasic();
int array[] = {1, 8, 6, 91, 52, 74, 5, 9};
int length = array.length;
Arrays.sort(array);
System.out.println(Arrays.toString(array));
System.out.println();
System.out.println(bs.binarySearch(array, 0, length - 1, 5)); // miss;
System.out.println(bs.binarySearch(array, 0, length - 1, 8)); // hit!
}
public int binarySearch(int array[], int low, int high, int desired) {
int mid = low + (high - low) /2;
int pivot = array[mid]; // get the middle element;
if (desired < pivot) {
binarySearch(array, low, mid - 1, desired); // since it's already smaller, use mid - 1 directly;
} else if (desired > pivot) {
binarySearch(array, mid + 1, high, desired); // same reason, use mid + 1 directly to skip mid;
} else {
return mid; // bingo!
}
return -1; // not found;
}
}
输出:
[1, 5, 6, 8, 9, 52, 74, 91]
-1
3
您没有基本情况。 递归需要一个基本案例来知道何时停止递归。 无限递归的结果是StackOverflowException
因为您正在调用且正在调用但未返回。 您将要进行无限递归。 二进制搜索的基本情况是hi
小于lo
。
您还希望将左呼叫从low
到m-1
而不是旋转,因为两端的边界都包含在内。
您还使用数据透视表VALUE作为索引! 而不是中间的INDEX :
binarySearch(array, low, pivot-1, desired);
应该:
binarySearch(array, low, m-1, desired);
方法:
public int binarySearch(int array [], int low, int high, int desired) {
// Not found
if (high < low)
return -1;
// Middle index
int m = low + (high - low) / 2;
// Middle value
int pivot = array[m];
if (desired < pivot)
binarySearch(array, low, m-1, desired);
else if (desired > pivot)
binarySearch(array, m+1, high, desired);
else
return m;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.