BinarySearch查找

本文深入讲解了二分查找算法的基本原理及其应用,包括一维数组的递归与非递归实现,以及二维数组的二分查找策略。通过具体实例演示了如何在有序数组中高效查找目标元素。

二分查找
要求: 数组有序
二分查找大大降低了比较次数,二分查找的时间复杂度为:O(log2n),即log{n}。
假使总共有n个元素,那么二分后每次查找的区间大小就是n,n/2,n/4,…,n/2^k(接下来操作元素的剩余个数),其中k就是循环的次数。
最坏的情况是K次二分之后,每个区间的大小为1,找到想要的元素
令n/2^k=1,
可得k=log2n,(是以2为底,n的对数),所以时间复杂度可以表示O()=O(logn).

package com.lyzz.BinarySearch;

public class BinarySearchDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] arr= {1,2,3,4,5,6,7,8,9,10};
		int x = BinarySearch1(arr, 3, 0, arr.length-1);
		System.out.println(x);
	}
	
	/**
	 * 递归实现
	 * @author Lxuex
	 * @param arr
	 * @param key
	 * @param low
	 * @param high
	 * @return
	 */
	public static int BinarySearch(int[] arr,int key,int low,int high) {
		if(key < arr[low] || key > arr[high] || low > high) {
			return -1;
		}
		
		int middle = (low + high) / 2;
		if(arr[middle] > key) { //比关键字大在关键字的左边
			return BinarySearch(arr,key,low,middle-1);
			
		}else if(arr[middle] < key) { //比关键字小在关键字的右边
			return BinarySearch(arr,key,middle+1,high);
			
		}else {
			return middle;
		}

	}
	
	/**
	 * 非递归实现
	 * @author Lxuex
	 * @param arr
	 * @param key
	 * @param low
	 * @param high
	 * @return
	 */
	public static int BinarySearch1(int[] arr,int key,int low,int high) {
		while (low <= high)
		{
			int mid = (low + high) / 2; // 取中间位置
			if (key > arr[mid])	   // 从关键字的右半部分继续查找
			{
				low = mid + 1;
			}
			else if (key < arr[mid]) // 从关键字的左半部分继续查找
			{
				high = mid - 1;
			}
			else if (key == arr[mid])
			{
				return mid; // 查找成功,则返回所在位置
			}
		}
		return -1; // 查找元素不存在,返回-1

	}
	

}

二维数组的二分查找:

/**
	 * 二分查找
	 * @param array
	 * @param target
	 * @return
	 */
	 public static boolean Find(int [][] array,int target) {
	        //二维数组的行数
	        int n=array.length-1;
	        //二维数组的索引
	        int i=0; 
	        //从左下角开始遍历
	        while(n>=0&&i<array[n].length){
	            //如果相等,直接返回true
	            //如果小于,二维索引++
	            //如果大于,一维索引—-
	            if(array[n][i]==target){
	                return true;
	            }else if(array[n][i]<target){
	                i++; 
	            }else {
	                n--;
	            }

	        }
	        //循环能够执行完毕,直接返回false
	        return false;

	    }

<think>好的,我现在需要帮助用户理解如何在Java中使用Arrays.binarySearch方法结合Comparable接口进行二分查找。用户之前已经询问过关于binarySearch的基本用法,现在更深入地想了解如何与Comparable接口结合使用。让我先回顾一下之前的回答和相关引用,确保信息准确。 首先,根据用户提供的引用,引用[2]提到对象数组必须实现Comparable接口,否则会报错。而引用[3]展示了使用Comparator的例子,但用户现在关注的是Comparable接口,所以可能需要比较这两个的不同。用户需要的是一个具体的示例,说明如何让自定义类实现Comparable,然后用binarySearch查找。 接下来,我需要确认用户的理解程度。他们可能已经知道基本用法,现在想应用到自定义对象上。因此,我应该详细说明实现步骤,并提供代码示例,确保每一步都清晰,比如如何实现Comparable的compareTo方法,如何排序数组,然后调用binarySearch。 还要注意可能的常见错误,例如忘记排序数组,或者compareTo方法实现不正确导致排序错误,从而影响二分查找的结果。需要提醒用户这些注意事项,避免他们在实际使用中遇到问题。 此外,引用[4]中的例子虽然使用的是String数组,但String类本身已经实现了Comparable接口,所以这也是一个很好的例子。可以提到这一点,说明系统内置类已经支持,而自定义类需要手动实现。 最后,生成相关问题时要围绕Comparable接口和binarySearch的深入使用,比如与Comparator的区别,处理重复元素等。确保用户能进一步扩展他们的知识。</think>### Java中使用Comparable接口实现二分查找的完整指南 #### 一、核心实现原理 1. **接口约束**:目标类必须实现`java.lang.Comparable`接口 2. **排序逻辑**:通过`compareTo()`方法定义对象比较规则 3. **查找基础**:`Arrays.binarySearch()`依赖`compareTo()`实现元素定位[^2] #### 二、实现步骤(以Student类为例) 1. **定义可比较对象** ```java class Student implements Comparable<Student> { int id; String name; @Override public int compareTo(Student other) { // 按ID升序排列 return Integer.compare(this.id, other.id); } } ``` 2. **准备排序数组** ```java Student[] students = { new Student(102, "张三"), new Student(105, "李四"), new Student(98, "王五") }; Arrays.sort(students); // 强制排序(触发compareTo方法) ``` 3. **执行二分查找** ```java Student target = new Student(105, ""); int index = Arrays.binarySearch(students, target); System.out.println("查找结果:" + index); // 输出1(排序后数组索引位置) ``` #### 三、关键代码解析 | 代码片段 | 作用说明 | 数学表达式 | |---------|---------|-----------| | `Integer.compare(a,b)` | 生成标准比较值 | $\text{sign}(a - b)$ | | `compareTo()`返回值 | 定义对象顺序 | 正数、零、负数对应$>, =, <$关系 | | 查找返回值 | 定位元素位置 | $结果 \geq 0$表示存在,$结果 < 0$表示插入点 | #### 四、特别注意事项 1. **排序一致性**:`compareTo()`实现必须与`equals()`方法逻辑一致[^2] 2. **多字段排序**处理: ```java @Override public int compareTo(Student other) { // 优先按ID,其次按姓名 int idCompare = Integer.compare(this.id, other.id); return (idCompare != 0) ? idCompare : this.name.compareTo(other.name); } ``` 3. **性能优化点**: - 避免在`compareTo()`中创建新对象 - 对大数组优先使用基本类型数组 - 预排序数据可复用 #### 五、完整示例验证 ```java public class ComparableSearchDemo { public static void main(String[] args) { Product[] products = { new Product("A102", 19.9), new Product("B205", 29.9), new Product("C301", 9.9) }; Arrays.sort(products); // 按compareTo规则排序 System.out.println(Arrays.toString(products)); Product key = new Product("B205", 0); int pos = Arrays.binarySearch(products, key); System.out.println("查找结果:" + pos); // 输出1 } } class Product implements Comparable<Product> { String sku; double price; @Override public int compareTo(Product other) { return this.sku.compareTo(other.sku); } } ``` --相关问题--: 1. 如何为多字段排序实现Comparable接口? 2. Comparable和Comparator在二分查找中的区别是什么? 3. 为什么binarySearch()要求数组必须预先排序? 4. 如何处理二分查找中的重复元素定位问题? [^1]: 基础二分查找实现要求 : 对象比较规范约束 [^3]: 排序算法依赖关系 [^4]: 插入点计算规则
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值