二分查找是一种常用的查找算法,也叫折半查找,它是针对有序数组进行的查找操作。其基本思想是:将有序数组一分为二,通过比较查找值与中间元素的大小,缩小查找范围,直到找到查找值或查找范围缩小为0为止。
具体的实现步骤如下:
- 定义左右指针,分别指向数组的第一个元素和最后一个元素
- 计算中间位置 mid,即 mid = (left + right) / 2
- 比较查找值和中间位置元素的大小,如果相等则直接返回中间位置元素下标,如果查找值小于中间元素,则在左半部分继续查找,否则在右半部分继续查找
- 重复执行步骤2和3,直到找到查找值或查找范围缩小为0
二分查找的时间复杂度是 O(logn),比线性查找的时间复杂度 O(n) 要快得多。但是,要使用二分查找,必须保证数组是有序的,否则无法正常执行查找操作。
一、C 二分查找 源码实现及详解
二分查找算法也称折半查找,它是一种在有序数组中查找特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;否则如果中间元素大于(小于)要查找的元素,依据大小关系,将数组的左半部分(右半部分)作为新的查找数组,然后继续执行查找算法,直到查找到要查找的元素或者数组为空为止。
下面是 C 语言实现二分查找的源码及详解:
#include <stdio.h>
int binarySearch(int arr[], int left, int right, int target) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
}
else if (arr[mid] < target) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
return -1;
}
int main(void) {
int arr[] = {1, 3, 5, 7, 9, 11, 13};
int n = sizeof(arr) / sizeof(arr[0]);
int target = 9;
int result = binarySearch(arr, 0, n-1, target);
if (result == -1) {
printf("Element is not present in array\n");
}
else {
printf("Element is present at index %d\n", result);
}
return 0;
}
该代码实现了一个基本的二分查找算法。函数 binarySearch
的参数包括 arr
数组,查找范围的左右端点下标 left
和 right
,以及要查找的目标值 target
。函数通过一个 while 循环进行查找,循环条件为左端点下标小于等于右端点下标。在每次循环中,函数通过计算中点下标(左下标加上右下标除以二)判断目标值在左半区间还是右半区间,如果中点的值正好等于目标值,直接返回中点的下标,否则不断更新左右端点,直到找到目标值或者没有剩余元素返回 -1。
在主函数中,定义了一个有序数组 arr
,并通过调用 binarySearch
函数在数组中查找目标值 9
。如果返回值为 -1,则说明目标值不存在于数组中,否则打印目标值在数组中的下标。
需要注意的是,使用二分查找算法查找的数组必须是有序的,否则无法正确找到目标元素。
二、C++ 二分查找 源码实现及详解
二分查找也叫折半查找,是一种在有序数组中查找特定元素的算法。它的工作原理是通过不断地将查找区间划分为两个子区间,直到找到目标元素为止。
C++ 二分查找的源码实现如下:
// 在有序序列中查找目标值,找到则返回其下标,否则返回 -1
int binarySearch(int arr[], int left, int right, int target) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
该函数的参数解释如下:
arr
:有序数组left
:查找区间的左边界right
:查找区间的右边界target
:目标值
函数的返回值为目标值在数组中的下标,如果找不到则返回 -1。
接下来我们对该算法进行详细解释:
- 初始化查找区间为整个数组,即
left = 0
,right = n-1
,其中n
是数组的长度。 - 通过计算中间位置
mid
,将查找区间划分为两个子区间:[left, mid-1]
和[mid+1, right]
。 - 如果目标值等于
arr[mid]
,则直接返回mid
。 - 如果目标值小于
arr[mid]
,说明目标值位于左子区间,将查找区间缩小为[left, mid-1]
。 - 如果目标值大于
arr[mid]
,说明目标值位于右子区间,将查找区间缩小为[mid+1, right]
。 - 重复步骤 2~5,直到找到目标值或者查找区间为空。
二分查找的时间复杂度为 O ( log n ) O(\log n) O(logn),因为每次查找都将查找区间缩小一半,所以最坏情况下需要进行 log 2 n \log_2 n log2n 次查找。
三、java 二分查找 源码实现及详解
Java 的二分查找算法是一种高效的查找算法,可以快速地从有序数组中查找指定的元素。下面是 Java 二分查找的源码实现及详解:
public static int binarySearch(int[] a, int key) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = a[mid];
if (midVal < key)
low = mid + 1;
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found
}
在上述代码中,binarySearch()
方法采用了迭代的方式实现二分查找算法。它接收两个参数:一个有序的数组 a
和要查找的元素 key
,并返回查找结果的下标。
首先,算法会初始化两个指针 low
和 high
,分别指向数组的第一个和最后一个元素。接着,算法在一个循环中对数组进行二分查找,直到找到指定的元素或者数组被完全遍历。
在每次迭代中,算法首先计算当前查找区间的中间位置 mid
。这里采用了无符号右移运算符 >>>
来代替普通的右移运算符,可以避免因为符号位的扩展而导致的问题。
计算出中间位置后,算法将中间位置对应的数组元素的值保存在 midVal
中。如果 midVal
小于要查找的元素 key
,则说明 key
在数组的右半部分,此时将 low
指针向右移动到 mid + 1
的位置;如果 midVal
大于要查找的元素 key
,则说明 key
在数组的左半部分,此时将 high
指针向左移动到 mid - 1
的位置;如果 midVal
等于要查找的元素 key
,则说明已经找到了,直接返回它的下标 mid
。
如果循环结束后仍然没有找到指定的元素,那么说明该元素不存在于数组中。根据二分查找算法的规定,此时应该返回一个负数,代表元素未找到。具体返回值的计算方式为 -(low + 1)
,其中 low
是指向数组第一个大于 key
的元素的指针,如果 key
所在的位置是 i
,则 low
的值就是 i + 1
。
以上就是 Java 二分查找算法的源码实现及详解。