二分查找思想:
待查找數組按照一定順序已經排好序,取數組中間位置的值,如果其值與待查找的值相等,則直接找到;如果其值大於待查找的值,待查找的值一定在初始位置與中間位置內,只需要在初始位置與中間位置內繼續進行二分查找即可;如果其值小於待查找的值,則待查找的值一定在中間位置與結束位置內,只需要在中間位置與結束位置內進行二分查找即可;如果直到起始位置大於結束位置都還沒有找到,則可以認爲待查找數不在此數組內。
假如需求上要求 : 待查找數有可能有多個,多個也要查找出來,則可以在查找到一個到時候,向左右兩邊探測,將所有相同的數的位置都返回即可。
代碼:
package cn.agan.mysearch;
import java.util.ArrayList;
/**
* 二分查找
*/
public class BinarySearch {
public static void main(String[] args) {
int[] a = {3, 5, 7, 23, 55, 77, 88};
int target = -1;
int index = binarySearch(a, 0, a.length-1, target);
if (index != -1) {
System.out.printf("要找的數:%d, 在%d, 值爲:%d\n", target, index, a[index]);
} else {
System.out.println("目標不在數組內");
}
}
public static int binarySearch(int[] a, int left, int right, int target) {
if (left > right) {
return -1;
}
int mid = (left+right) / 2;
int midVal = a[mid];
if (target > midVal) {
return binarySearch(a, mid+1, right, target);
} else if (target < midVal) {
return binarySearch(a, left, mid-1, target);
} else {
return mid;
}
}
//當一個數組中包含相同的數值,而且剛好是要查找的值時,返回它們
//思路:在找到mid索引的時候,不馬上返回,向mid左右兩邊掃描,把所有滿足要求的下標都返回去
public static ArrayList<Integer> binarySearchSameVal(int[] a, int left, int right, int target) {
if (left > right) {
return new ArrayList<Integer>();
}
int mid = (left+right) / 2;
int midVal = a[mid];
if (target > midVal) {
return binarySearchSameVal(a, mid+1, right, target);
} else if (target < midVal) {
return binarySearchSameVal(a, left, mid-1, target);
} else {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(mid);
int tmp = mid-1;
while (true) {
if (tmp < 0 || a[tmp] != target) {
break;
}
integers.add(tmp);
tmp--;
}
tmp = mid+1;
while (true) {
if (tmp > a.length || a[tmp] != target) {
break;
}
integers.add(tmp);
tmp++;
}
return integers;
}
}
}