二分查找法(折半查找法):查找數組中是否包含指定元素。如果包含指定元素,則返回指定元素的index(從0開始);如果不包含指定元素,則返回-1;
前提:數組中的元素必須是有序的。
原理:將被查找的數組分爲三部分,依次是中值前、中值、中值後,將指定元素和數組的中值進行比較,如果指定元素小於中值則在(中值前)中找,如果指定元素大於中值則在(中值後)中找,如果指定元素等於中值則直接返回。依次查找後,如果不包含指定元素,則返回-1;
注:中值即數組中間位置的值。
原生方法:Arrays.sort(a);:對a數組進行升序排序。
Arrays.binarySearch(a,b);:使用二分法查找a數組中是否包含b這個元素。
自定義方法:
兩種方式:循環實現和遞歸實現
/**
* 循環實現
* 二分查找法(折半查找法):查找數組中是否包含指定元素。
* 前提:數組中的元素必須是有序的。
* Arrays.sort(a);:對a數組進行升序排序。
* Arrays.binarySearch(a,b);:使用二分法查找a數組中是否包含b這個元素。
*
* @param arr 被查找的數組
* @param key 指定元素
* @return 如果包含指定元素,則返回指定元素的index(從0開始);如果不包含指定元素,則返回-1;
*/
public static int binarySearch(int[] arr, int key) {
int min = 0;
int max = arr.length - 1;
while (min <= max) {
int mid = (min + max) >> 1;//(min + max)/2
if (arr[mid] > key) {
max = mid - 1;
} else if (arr[mid] < key) {
min = mid + 1;
} else {
return mid;
}
}
return -1;
}
/**
* 遞歸實現
* 二分查找法(折半查找法):查找數組中是否包含指定元素。
* 前提:數組中的元素必須是有序的。
* Arrays.sort(a);:對a數組進行升序排序。
* Arrays.binarySearch(a,b);:使用二分法查找a數組中是否包含b這個元素。
*
* @param arr 被查找的數組
* @param key 指定元素
* @return 如果包含指定元素,則返回指定元素的index(從0開始);如果不包含指定元素,則返回-1;
*/
public static int binarySearch(int[] arr, int key, int startIndex, int endIndex) {
if (startIndex > endIndex || startIndex < 0 || endIndex > arr.length - 1) {
return -1;
}
int midIndex = (startIndex + endIndex) >> 1;//(startIndex + endIndex)/2
if (arr[midIndex] > key) {
return binarySearch(arr, key, startIndex, midIndex - 1);
} else if (arr[midIndex] < key) {
return binarySearch(arr, key, midIndex + 1, endIndex);
} else {
return midIndex;
}
}
驗證:
//驗證自定義的二分查找法
int[] a = {};
int[] b = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] c = {1, 4, 6, 7, 8, 3, -2};
//循環實現
int circulate1 = binarySearch(a, 0);
int circulate2 = binarySearch(b, 5);
int circulate3 = binarySearch(c, -2);
Arrays.sort(c);
int circulate4 = binarySearch(c, -2);
LogUtil.e("++++++++++++++++", circulate1 + ""); //-1
LogUtil.e("++++++++++++++++", circulate2 + ""); //4
LogUtil.e("++++++++++++++++", circulate3 + ""); //-1
LogUtil.e("++++++++++++++++", circulate4 + ""); //0
//遞歸實現
int recursion1 = binarySearch(a, 0, 0, a.length - 1);
int recursion2 = binarySearch(b, 5, 0, b.length - 1);
int recursion3 = binarySearch(c, -2, 0, c.length - 1);
LogUtil.e("++++++++++++++++", recursion1 + ""); //-1
LogUtil.e("++++++++++++++++", recursion2 + ""); //4
LogUtil.e("++++++++++++++++", recursion3 + ""); //0