今日分享 二分算法及多语言实现
一、二分算法是什么?
二分算法(Binary Search)是一种高效的查找算法,核心思想是“每次将查找范围缩小一半”,仅适用于有序数组(升序或降序)。相比线性查找(逐个遍历,时间复杂度O(n)),二分查找的时间复杂度仅为O(log₂n),数据量越大,效率优势越明显(如n=100万时,线性查找最多需100万次,二分查找最多仅需20次)。
二、二分算法的核心原理
以“升序数组中查找目标值”为例,步骤如下:
1. 初始化边界:定义左指针 left (指向数组起始位置,初始值0)、右指针 right (指向数组末尾位置,初始值 数组长度-1 );
2. 计算中间位置:每次取 mid = left + (right - left) / 2 (避免 left+right 溢出,优于 (left+right)/2 );
3. 比较与缩范围:
若 nums[mid] == 目标值 :找到目标,返回 mid (索引);
若 nums[mid] < 目标值 :目标在右半区,更新 left = mid + 1 ;
若 nums[mid] > 目标值 :目标在左半区,更新 right = mid - 1 ;
4. 循环终止:当 left > right 时,说明数组中无目标值,返回 -1 (表示未找到)。
三、经典例题:二分查找目标值
题目描述
给定一个升序排列的整数数组 nums 和一个目标值 target ,请查找 target 在 nums 中的索引;若不存在,返回 -1 。
示例:
输入: nums = [-1, 0, 3, 5, 9, 12] , target = 9
输出: 4 (9在数组中索引为4)
输入: nums = [-1, 0, 3, 5, 9, 12] , target = 2
输出: -1 (2不在数组中)
四、多语言实现代码
1. C语言实现
#include <stdio.h>
// 二分查找函数:返回目标值索引,未找到返回-1
int binarySearch(int nums[], int numsSize, int target) {
int left = 0;
int right = numsSize - 1; // 初始右边界为数组末尾
while (left <= right) { // 循环条件:左<=右(覆盖所有可能位置)
int mid = left + (right - left) / 2; // 避免溢出
if (nums[mid] == target) {
return mid; // 找到目标,返回索引
} else if (nums[mid] < target) {
left = mid + 1; // 目标在右半区,更新左边界
} else {
right = mid - 1; // 目标在左半区,更新右边界
}
}
return -1; // 未找到目标
}
int main() {
int nums[] = {-1, 0, 3, 5, 9, 12};
int numsSize = sizeof(nums) / sizeof(nums[0]);
int target1 = 9, target2 = 2;
printf("目标值%d的索引:%d\n", target1, binarySearch(nums, numsSize, target1)); // 输出4
printf("目标值%d的索引:%d\n", target2, binarySearch(nums, numsSize, target2)); // 输出-1
return 0;
}
2. C++实现
#include <iostream>
#include <vector>
using namespace std;
// 二分查找函数:参数为vector数组,返回索引
int binarySearch(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
int main() {
vector<int> nums = {-1, 0, 3, 5, 9, 12};
int target1 = 9, target2 = 2;
cout << "目标值" << target1 << "的索引:" << binarySearch(nums, target1) << endl; // 4
cout << "目标值" << target2 << "的索引:" << binarySearch(nums, target2) << endl; // -1
return 0;
}
3. Python实现
def binary_search(nums, target):
left = 0
right = len(nums) - 1 # 初始右边界为数组长度-1
while left <= right:
mid = left + (right - left) // 2 # Python整数除法用//
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# 测试
nums = [-1, 0, 3, 5, 9, 12]
target1 = 9
target2 = 2
print(f"目标值{target1}的索引:{binary_search(nums, target1)}") # 4
print(f"目标值{target2}的索引:{binary_search(nums, target2)}") # -1
4. Java实现
public class BinarySearch {
// 静态方法:二分查找,参数为int数组和目标值
public static int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
public static void main(String[] args) {
int[] nums = {-1, 0, 3, 5, 9, 12};
int target1 = 9, target2 = 2;
System.out.println("目标值" + target1 + "的索引:" + binarySearch(nums, target1)); // 4
System.out.println("目标值" + target2 + "的索引:" + binarySearch(nums, target2)); // -1
}
}
5. PHP实现
<?php
// 二分查找函数:参数为数组和目标值
function binarySearch($nums, $target) {
$left = 0;
$right = count($nums) - 1; // count()获取数组长度
while ($left <= $right) {
$mid = $left + intval(($right - $left) / 2); // intval()确保整数
if ($nums[$mid] == $target) {
return $mid;
} elseif ($nums[$mid] < $target) {
$left = $mid + 1;
} else {
$right = $mid - 1;
}
}
return -1;
}
// 测试
$nums = [-1, 0, 3, 5, 9, 12];
$target1 = 9;
$target2 = 2;
echo "目标值{$target1}的索引:" . binarySearch($nums, $target1) . "<br>"; // 4
echo "目标值{$target2}的索引:" . binarySearch($nums, $target2) . "<br>"; // -1
?>
6. JavaScript实现
// 二分查找函数:参数为数组和目标值
function binarySearch(nums, target) {
let left = 0;
let right = nums.length - 1; // length获取数组长度
while (left <= right) {
const mid = left + Math.floor((right - left) / 2); // Math.floor()向下取整
if (nums[mid] === target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
// 测试
const nums = [-1, 0, 3, 5, 9, 12];
const target1 = 9, target2 = 2;
console.log(`目标值${target1}的索引:${binarySearch(nums, target1)}`); // 4
console.log(`目标值${target2}的索引:${binarySearch(nums, target2)}`); // -1