又到了一年一季的招聘季,二分搜索是一个烂大街的题目,相信会写的人不少,当你能真正知道错误写法到底错在哪里吗?
错误一,因结束条件判断错误,数组中明明存在key,但程序却却找不到
public static int binary_search(int [] array, int key, int begin, int end) { int mid; while(begin<end) { mid = begin + (end - begin)/2; System.out.println("begin = " + begin + " mid = " + mid + " end = " + end); if (array[mid]==key) { return mid; } if(array[mid]>key) { end = mid -1; } else { begin = mid + 1; } } return 0; }
测试用的代码:
int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 13, 19};
int index = BinarySearch.search(array, 4, 0, 9);
System.out.println("index = " + index);
执行的结果:
begin = 0 mid = 5 end = 10
begin = 0 mid = 2 end = 4
begin = 3 mid = 3 end = 4
index = 0
你会发现明明数组中存在4,但却没有找到。原因就是判断程序结束时使用了:左闭右开的区间:[0, n)。 因此,当这个条件满足时,end应该为mid (已判断要搜索的key不是mid), 而在这里right赋值为middle - 1了, 判断区间为:[0, middle-1),那么就会遗漏array[middle - 1] = v的情况。
错误二,无限循环
public static int binary_search (int [] array, int key, int begin, int end) {
int mid;
while(begin<=end) {
mid = begin + (end - begin)/2;
System.out.println("begin = " + begin + " mid = " + mid + " end = " + end);
if (array[mid]==key) {
return mid;
}
if(array[mid]>key) {
end = mid;
}
else {
begin = mid;
}
}
return 0;
}
int array[] = {1, 2, 3, 3, 5, 7, 8, 13, 15,19};
int index = BinarySearch.search_1(array, 4, 0, 9);
执行的结果:
begin = 0 mid = 4 end = 9
begin = 0 mid = 2 end = 4
begin = 2 mid = 3 end = 4
begin = 3 mid = 3 end = 4
begin = 3 mid = 3 end = 4
begin = 3 mid = 3 end = 4
begin = 3 mid = 3 end = 4
无限循环
原因:因为while(begin<=end),而且:begin=mid或begin=end,所以当mid=begin而且找不到key的时候会死循环。
正确的写法:
public static int binary_search(int [] array, int key, int begin, int end) { int mid; while(begin<=end) { mid = begin + (end - begin)/2; //System.out.println("begin = " + begin + " mid = " + mid + " end = " + end); if (array[mid]==key) { return mid; } if(array[mid]>key) { end = mid -1; } else { begin = mid + 1; } } return 0; }
int array[] = {1, 2, 3, 3, 5, 7, 8, 13, 15,19};
int index = BinarySearch.search(array, 5, 0, 10);
执行结果:
begin = 0 mid = 5 end = 10
begin = 0 mid = 2 end = 4
begin = 3 mid = 3 end = 4
begin = 4 mid = 4 end = 4
index = 4