數據結構–查找
二分查找
- 方法一:軸點取中點,逐步遞歸。算法時間複雜度O(log[n])。主要思路如下圖:
<pre>
public class LinearRecur {
public static void main(String[] args) {
int[] b = {2,6,6,9,10,10};
int low = 0;
int high = b.length;
int index = 0;
index = binarySearch(b, low,high, 2);
System.out.print(index);
}
public static int binarySearch(int[] array, int low, int high, int num) {
if(high - low == 1) {
if (array[low] == num) {
return low;
}
return -1;
}
int middle = 0;
int index = 0;
middle = (low + high) / 2;
if (num == array[middle]) {
return middle;
}
if (num < array[middle]) {
index = binarySearch(array, low, middle, num);
return index;
}
if (array[middle] < num) {
index = binarySearch(array, middle+1, high, num);
return index;
}
return -1; //不會執行
}
}
</pre>
對於該算法,我們可以計算出迭代到底部所耗費的時間,計算結果如下圖所示。從圖中可以看出左邊遞歸和右邊遞歸所耗費的步數是不一樣的,那我我們是否可以找到一種算法讓左邊迭代步數和右邊一致能,這樣能夠減少平均迭代時間。如下圖所示的斐波那契搜索每次迭代不再是選擇中點進行分割。進而,對於這個問題我們可以找到最優的黃金分割點實現最低的時間複雜度。
2. 方法二:二分查找的改進策略。爲了解決左右兩邊搜索不平衡問題,我們需要做一些操作,即讓左右兩邊的判斷次數一致,即:
<pre>
public class LinearRecur {
public static void main(String[] args) {
int[] b = {2,6,6,9,10,11};
int low = 0;
int high = b.length;
int index = 0;
index = binarySearch(b, low, high, 2);
System.out.print(index);
}
public static int binarySearch(int[] array, int low, int high, int num) {
if (num == array[low]) {
return low;
}else if(high - low == 1) {
return -1;
}
int middle = 0;
int index = 0;
middle = (low + high) / 2;
if (num < array[middle]) {
index = binarySearch(array, low, middle, num);
return index;
}else {
index = binarySearch(array, middle, high, num);
return index;
}
}
}
</pre>
3.方法三:二分查找的改進策略。對於一個二分查找算法,我們一般存在一些語義約定。對於一個有序數組,我們總希望查找後的返回的index能夠爲我們接下來的一些操作帶來便利。例如,我們希望在新的數組中插入一個數而不改變原數組的有序性,那麼我們對在原數組中查找返回的結果總是存在一定語義要求,爲了滿足我們的語義要求,我們可以通過下述算法來實現。總體的思路如下:
<pre>
public class LinearRecur {
public static void main(String[] args) {
int[] b = {2,6,6,9,10,11};
int low = 0;
int high = b.length;
int index = 0;
index = binarySearch(b, low, high, 10);
System.out.print(index);
}
public static int binarySearch(int[] b, int low, int high, int num) {
int index = 0;
while(low < high) {
int middle = 0;
middle = (low + high) / 2;
if (num < b[middle]) {
high = middle;
}else {
low = middle + 1;
}
}
return --low;
}
}
iddle]) {
high = middle;
}else {
low = middle + 1;
}
}
return --low;
}
}
</pre>