二分查找的理解(java程序举例)

本文深入解析二分查找算法,介绍其高效查询有序数列及插入位置的原理,通过Java实例展示运行过程,适用于理解二分查找的核心思想。

二分查找的解释

         二分查找又叫做折半查找,其作用有两个,一是可以高效的查询有序的数列中是否存在要查询的元素以及元素的位置,二是如果要往有序的数列中插入一个数,可以高效的查找到添加位置(但是由于其存储结构是顺序的,因此插入时效率低),由于其查找原理的好处使得二分查找的最坏情况的时间复杂度也为O(log2n),要优于顺序查找,其查找原理稍后用实例解释。

需要满足的条件

  1. 二分查找是针对大小有序的数列来说的,不管是从大到小还是从小到大
  2. 要查找的数据必须是一种顺序的存储结构

先看一个java实例

该例中我封装了一个二分查找的方法,进行了一次模拟调用,先尝试看懂代码,在程序运行截图后面我描述了整个运行过程,可以帮助理解,中间的输出语句是输出区间范围的,已经注释掉了。

public class Binary {
	public static void main(String[] args) {
		int arr[] = { 3, 7, 8, 11, 45, 56, 66, 68, 79, 82, 99 };
		Binary bi = new Binary();
		int location = bi.getLocation(66, arr);
		if (location > 0) {//location表示查找返回的位置,没有找到返回0
			System.out.println("该数出现在第" + location + "位置");
		} else {
			System.out.println("无此数");
		}
	}

	/**
	 * 该方法内封装了二分查找
	 * 
	 * @param data
	 *            传入一个int型数据
	 * @param arr
	 *            传入一个int型数组
	 * @return 返回元素位置,没查到返回0
	 */
	public int getLocation(int data, int arr[]) {
		// 采用二分查找每次都要缩小查找区间范围,begin是区间首位数字下标,end相反
		int begin = 0, end = arr.length - 1;
		// 用于记录 要查找数字存在的位置
		int location = 0;
		// 保证要查找的数字在该数组的区间范围内
		if (data >= arr[0] && data <= arr[arr.length - 1]){
			while (end - 1 > begin) {  //当区间元素相邻则退出循环 
				int mid = (begin + end) / 2;    //mid是取区间的中间数,与data比较之后可以缩小比较的区间范围
				if (data > arr[mid]) {
					begin = mid;  //在满足data比中间数大的时候,则把中间数下标赋值给begin,因此缩小了比较区间
					//System.out.println("中间值为"+mid+"     重新确定区间为" + arr[begin] + " " + arr[end]);
				} else if (data < arr[mid]) {
					end = mid;
					//System.out.println("中间值为"+mid+"     重新确定区间为" + arr[begin] + " " + arr[end]);
				} else {
					//System.out.println("中间值为"+mid);
					location = mid + 1;
					break;//当遇到相同元素记录该下标并强制退出循环
				}
			}
		}
		if(location==0){//上述循环完成后有可能漏掉begin和end下标表示的元素,因此在比较一下
			if (arr[begin] == data)
				location = begin + 1;
			if (arr[end] == data)
				location = end + 1;
		}
		return location;
	}
}

运行结果为

运行过程描述如下

       从截图可以看出,在进行二分查找的过程中,两次重新确定该值的区间,在 3, 7, 8, 11, 45, 56, 66, 68, 79, 82, 99中查找66

  1. 第一遍下标begin=0,end=10,mid=5,因此mid下标指示的数字是56,66>56因此区间改变,begin=mid=5
  2. 第二遍下标begin=5,end=10,mid=7,因此mid下标指示的数字是68,66<68因此区间改变,end=mid=7
  3. 第三遍下标begin=5,end=7,mid=6,因此mid下标指示的数字是66,因此确定了位置,循环强制退出

 

# 题目重述 问题是“二分查找解析”,这是对一种高效查找算法的原理与实现进行理解的需求,属于算法类问题。 # 详解 **二分查找**(Binary Search)是一种在**有序数组**中查找特定元素的高效算法。它通过不断缩小搜索范围,将时间复杂度从线性 $O(n)$ 降低到对数 $O(\log n)$。 ### 核心思想: 每次取中间元素与目标值比较: - 若相等 → 找到目标,返回索引; - 若中间值 < 目标值 → 目标在右半区; - 若中间值 > 目标值 → 目标在左半区; 然后在新区间重复此过程,直到找到或区间为空。 ### 算法步骤: 1. 定义左边界 `left = 0`,右边界 `right = n - 1`。 2. 当 `left <= right` 时循环执行: a. 计算中点:`mid = (left + right) / 2` b. 比较 `arr[mid]` 与目标值 `target`: - 相等 → 返回 `mid` - `arr[mid] < target` → `left = mid + 1`(去右半区) - `arr[mid] > target` → `right = mid - 1`(去左半区) 3. 若未找到,返回 `-1`。 ### 举例说明: 数组:$[1, 3, 5, 7, 9, 11]$,查找 `target = 7` - 第1轮:`left=0`, `right=5`, `mid=2`, `arr[2]=5 < 7` → `left = 3` - 第2轮:`left=3`, `right=5`, `mid=4`, `arr[4]=9 > 7` → `right = 3` - 第3轮:`left=3`, `right=3`, `mid=3`, `arr[3]=7 == 7` → 找到,返回 `3` ### Java 实现代码: ```java public static int binarySearch(int[] arr, int target) { int left = 0; int right = arr.length - 1; while (left <= right) { int mid = (left + right) / 2; // 可优化为 left + (right - left)/2 防溢出 if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; // 未找到 } ``` > ⚠️ 注意:二分查找的前提是数组必须**已排序**,否则结果不可靠。 # 知识点 - **循环与条件控制**:使用 `while` 循环持续缩小区间直至命中或越界。 - **数组与索引操作**:通过下标访问中间元素并比较。 - **分治思想**:每次将搜索空间缩小一半,提升查找效率。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值