二分查找(binary search)也称折半查找(half-interval search),二分查找首先要求原始数组是有序的,每次将数组中间的一个元素与待查找元素进行比较,如果相等则返回,如果中间元素小于待查找元素,则在数组的后半部分递归的进行相同的操作,反之,如果中间元素大于待查找元素,则在数组的前半部分进行查找,直至找到待查找元素,如果找不到则返回-1。该算法有两种实现方法:递归法和循环法。
时间复杂度为
O
(
log
n
)
\Omicron({\log} n)
O(logn)
public class BinarySearch {
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 11, 20, 440, 2220};
int target = 222;
// binarySearchRecursion(a, target, 0, a.length - 1);
binarySearch(a, target, 0, a.length - 1);
}
//递归法
public static int binarySearchRecursion(int[] arr, int target, int left, int right) {
if (left > right) {
System.out.println("没有该元素");
return -1;
}
int middle = (left + right) / 2;
if (arr[middle] == target) {
System.out.println(arr[middle] + "的下标是:" + middle);
return target;
} else if (arr[middle] < target) {
return binarySearchRecursion(arr, target, middle + 1, right);
} else {
return binarySearchRecursion(arr, target, left, middle - 1);
}
}
//while循环法
public static void binarySearch(int[] arr, int target, int left, int right) {
if (left > right) {
System.out.println("没有该元素");
return;
}
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == target) {
System.out.println(arr[mid] + "的下标是:" + mid);
return;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
System.out.println("没有该元素");
}
}
以下代码来自维基百科
维基百科地址
示例代码
C 版本- 递归
int binary_search(const int arr[], int start, int end, int khey) {
if (start > end)
return -1;
int mid = start + (end - start) / 2; //直接平均可能會溢位,所以用此算法
if (arr[mid] > khey)
return binary_search(arr, start, mid - 1, khey);
else if (arr[mid] < khey)
return binary_search(arr, mid + 1, end, khey);
else
return mid; //最後檢測相等是因為多數搜尋狀況不是大於要不就小於
}
C 版本- while 循环
int binary_search(const int arr[], int start, int end, int key) {
int ret = -1; // 未搜索到数据返回-1下标
int mid;
while (start <= end) {
mid = start + (end - start) / 2; //直接平均可能會溢位,所以用此算法
if (arr[mid] < key)
start = mid + 1;
else if (arr[mid] > key)
end = mid - 1;
else { // 最後檢測相等是因為多數搜尋狀況不是大於要不就小於
ret = mid;
break;
}
}
return ret; // 单一出口
}