1 回答

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個(gè)贊
您的算法不起作用,因?yàn)槟趯?duì)一個(gè)空數(shù)組進(jìn)行索引、排序和傳遞給您的函數(shù)。您可能在iArraySize和之間感到困惑aiNumbers;這兩個(gè)都是誤導(dǎo)性的變量名稱(chēng),因?yàn)槟鷮⒆址Q(chēng)添加到iArraySize并且aiNumbers不包含數(shù)字。您的二分搜索函數(shù)名稱(chēng)和其他變量同樣具有誤導(dǎo)性;即使函數(shù)頭采用數(shù)組,它們也使用單詞Numbers和前綴 。iString[]
此外,如果在數(shù)組中找不到目標(biāo),您的代碼將破壞調(diào)用堆棧。經(jīng)典的二分查找會(huì)返回失敗一次lo > hi;我想不出任何不包括base case 的理由。
另一個(gè)二分搜索問(wèn)題是使用公式mid = (hi - lo) / 2 + lo。這避免了如果hi + lo > Integer.MAX_SIZE.
這段代碼通過(guò)在整個(gè)過(guò)程中堅(jiān)持一個(gè)數(shù)組來(lái)解決這些問(wèn)題,使用更準(zhǔn)確的變量名并且不會(huì)溢出堆棧:
import java.util.*;
import java.security.SecureRandom;
class Main {
private static int recursiveCalls = 0;
public static void main(String[] args) {
runRecursiveTest();
}
public static void runRecursiveTest() {
SecureRandom rand = new SecureRandom();
String[] names = {
"John",
"Max",
"Kyle",
"Sam",
"Robert",
"Alex",
"Bob",
"Daniel",
"Felix",
"Michael"
};
String target = names[rand.nextInt(names.length)];
Arrays.sort(names);
System.out.println("Target string: " + target);
System.out.println("--- Begin Binary Search ---");
long begin = System.nanoTime();
System.out.println(bisect(names, target, 0, names.length - 1));
long end = System.nanoTime();
System.out.println("Elapsed time: " + (end - begin));
System.out.println("Recursive calls: " + recursiveCalls);
System.out.println("--- End Binary Search ---");
}
private static int bisect(String[] arr, String target, int lo, int hi) {
recursiveCalls++;
if (lo > hi) { return -1; }
int mid = (hi - lo) / 2 + lo;
if (target.equals(arr[mid])) {
return mid;
}
else if (target.compareTo(arr[mid]) > 0) {
return bisect(arr, target, mid + 1, hi);
}
return bisect(arr, target, lo, mid - 1);
}
}
輸出:
Target string: Sam
--- Begin Binary Search ---
9
Elapsed time: 81385
Recursive calls: 4
--- End Binary Search ---
添加回答
舉報(bào)