BinarySearch 在列表中找不到元素,即使它在那里:Java
谁能指出我哪里出错了?我用调试器单步调试它,看起来我的算法应该找到搜索键,但事实并非如此。 (为了进行检查,我打印出了“在索引处找到”,然后打印了[已排序]列表的内容;我搜索的元素 123 位于列表中,但返回了“未找到”值 -1。)
public int binarySearch(ArrayList<Integer> list, int key){
int foundAtIndex = -1;
int midPoint = list.size()/2;
int midPointValue = list.get(midPoint);
if(list.size() > 1){
if(midPointValue == key){
foundAtIndex = midPoint;
}
else if(midPointValue > key){
ArrayList<Integer> newList = new ArrayList<Integer>();
for(int i = 0; i < midPoint; i++){
newList.add(list.get(i));
}
midPoint = midPoint / 2;
binarySearch(newList, key);
}
else if(midPointValue < key){
ArrayList<Integer> newList = new ArrayList<Integer>();
for(int j = midPoint+1; j < list.size(); j++){
newList.add(list.get(j));
}
midPoint = midPoint / 2;
binarySearch(newList, key);
}
}
else if(list.size() == 1){
if(list.get(0) == key){
foundAtIndex = 0;
}
}
//return the index where the key was found, or -1 if not found
return foundAtIndex;
}
编辑:好的,现在它找到了它,但我的问题是我需要返回它在原始数组中找到的索引。事实上,它缩小了范围,然后返回“newList”中元素的索引。因此,它总是会返回在“newList”索引中找到的内容。换句话说,我希望返回一个实际的 findAtIndex (该值位于原始数组中的位置),而不是一个布尔值,“已找到/未找到”值。
Can anyone point out where I've gone wrong here? I stepped through it with a debugger and it looks like my algorithm should be finding the search key, but its not. (To check, I printed out the 'found at index' and then the contents of the [sorted] list; the element I searched for, 123, was in the list, but returned a 'not found' value of -1.)
public int binarySearch(ArrayList<Integer> list, int key){
int foundAtIndex = -1;
int midPoint = list.size()/2;
int midPointValue = list.get(midPoint);
if(list.size() > 1){
if(midPointValue == key){
foundAtIndex = midPoint;
}
else if(midPointValue > key){
ArrayList<Integer> newList = new ArrayList<Integer>();
for(int i = 0; i < midPoint; i++){
newList.add(list.get(i));
}
midPoint = midPoint / 2;
binarySearch(newList, key);
}
else if(midPointValue < key){
ArrayList<Integer> newList = new ArrayList<Integer>();
for(int j = midPoint+1; j < list.size(); j++){
newList.add(list.get(j));
}
midPoint = midPoint / 2;
binarySearch(newList, key);
}
}
else if(list.size() == 1){
if(list.get(0) == key){
foundAtIndex = 0;
}
}
//return the index where the key was found, or -1 if not found
return foundAtIndex;
}
EDIT: Okay, so it finds it now, but my problem is I need to return the index it was found at in the original array. As it is, it narrows it down then returns the index of the element in 'newList'. So it will always return it as being found at an index in terms of 'newList'. In other words, I'm looking to return an actual foundAtIndex (at what position the value is located at in the original array) as opposed to a boolean, "was/wasn't found" value.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
每次调用
binarySearch(newList, key);
时,您都会丢失返回结果。您需要设置
foundIndex = binarySearch(newList,key)
。另外,因为您依赖
list.size()
作为中点 - 您将需要调整返回结果(否则它将始终为 -1 或 0)。Every time you call
binarySearch(newList, key);
you are losing the return result.You need to set
foundIndex = binarySearch(newList,key)
.Also, because you are relying on
list.size()
for the midpoint - you are going to need to adjust your return result (otherwise it will always be -1 or 0).您不存储递归调用的返回值。将这两行替换
为
它应该可以工作。
You don't store the return values of the recursive calls. Substitute the two lines
by
and it should work.
这是一个返回原始列表中索引的解决方案。主要变化:当您对 binarySearch 进行递归调用时,您将
newList
的偏移量添加到其结果中(与list
相比)。在midPointValue>中key 这个偏移量为零,因此无需添加任何内容。如果 midPointValuekey
则偏移量为midPoint
。附加点:
midPoint
和midPointValue
中的point
有点多余。变量名称太长会使代码更难理解。下面是我如何编写这个方法:
Here's a solution that returns the index at the original list. The main change: when you make a recursive call to binarySearch you add to its result the offset of
newList
(compared tolist
). InmidPointValue > key
this offset is zero so there's nothing to add. IfmidPointValue < key
then the offset ismidPoint
.Additional points:
point
inmidPoint
andmidPointValue
is kind of superfluous. Varialbe names that are too long make it harder to understand the code.Here's how I'd write this method: