目錄
1. 二分查找基本概念
二分查找也稱折半查找(Binary Search),它是一種效率較高的查找方法。但是,折半查找要求線性表必須採用順序存儲結構,而且表中元素按關鍵字有序排列。
關鍵:
1.必須採用順序存儲結構。
2.必須按關鍵字大小有序排列。
二分查詢的次數,最多不超過
2. 二分查找的思路
二分查找的思路其實很簡單,二分,顧名思義就是一分爲二,由於二分法的前提是必須爲有序的、順序存儲的,所以如果當前線性表(一般爲數組)中間的值不是我們要查找的值時,我們要查找的值,要麼在中間的左邊,要麼在中間的右邊。如果在中間的左邊,則我們將左邊的線性表重新一分爲二,繼續查詢。
示意圖:
(圖片來源於網絡,侵權刪)
3.代碼實現
本次代碼實現以兩種方式編寫,遞歸和非遞歸,基本每行都有註釋:
/**
* @author 浪子傑
* @version 1.0
* @date 2020/6/4
*/
public class BinarySearchDemo {
public static void main(String[] args) {
int[] arr = {1, 2, 5, 7, 9, 12, 15, 22};
System.out.println(binarySearch(arr, 12));
System.out.println(binarySearchByRecursion(arr, 0, arr.length, 9));
}
/**
* 二分查找算法(非遞歸)
*
* @param arr 有序數組(從小到大排序)
* @param target 目標值
* @return -1:表示沒有找到;否則返回目標值的下標
*/
public static int binarySearch(int[] arr, int target) {
// 獲取初始左下標
int left = 0;
// 獲取初始右下標
int right = arr.length - 1;
// 如果左下標小於右下標,則進行循環查找
while (left < right) {
// 獲取中間下表
int mid = (left + right) / 2;
// 如果當前下標值==目標值,則返回
// 如果當前下標值大於目標值,則說明應該向當前下標左部查找
// 如果當前下標值大於目標值,則說明應該向當前下標右部查找
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) {
right = mid - 1;
} else if (arr[mid] < target) {
left = mid + 1;
}
}
// 如果循環過後還沒找到,說明該數組中沒有目標值
return -1;
}
/**
* 二分查找算法(遞歸)
*
* @param arr 有序數組(從小到大)
* @param left 左下標
* @param right 右下標
* @param target -1:未命中;否則返回目標值下標
* @return
*/
public static int binarySearchByRecursion(int[] arr, int left, int right, int target) {
// 如果左下標大於右下標直接返回-1
if (left > right) {
return -1;
}
// 算出左下標和右下標的中間下標
int mid = (left + right) / 2;
// 判斷
// 如果中間下標的值==目標值,返回中間下標
// 如果中間下標大於目標值,則說明目標值位於中間下標左側,將右下標設爲中間下標-1,遞歸
// 如果中間下標小於目標值,則說明目標值位於中間下標右側,將左下標設爲中間下標+1,遞歸
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) {
return binarySearchByRecursion(arr, left, mid - 1, target);
} else if (arr[mid] < target) {
return binarySearchByRecursion(arr, mid + 1, right, target);
}
return -1;
}
}