二分查找-变种

最简单的二分查找

图片分析

解释:

  1. 假设要查找的数字是6(value)
  2. 定义要查找数组的边界值,首先找到数组的中间值下标
  3. 如果小于value,说明要找的值在右边将数组最小值设为:中间值+1
  4. 依次类推直至找到value相等的下标,或者最大最小指针指向一个下标停止

代码实现

public static int search(int [] items,int value){
		int low = 0;
		int high = items.length-1;
		while (low <= high){
			//获取中间值:类似于(low+high)/2
			int mid = low + ((high - low) >> 1);
			if (items[mid] > value){
				high = mid - 1;
			}else if (items[mid] < value){
				low = mid +1;
			}else {
				return mid;
			}
		}
		return -1;
	}

上面是最简单的二分查找,单只能单纯的判断是否存在value,如果数组存在多个value,比如要查找第一个相等的下标,这个就有的不好使了:{1,2,3,4,4,4,6,7,8}这个数组返回的下标就是4,而实际我们想要的是3

变种1:查找第一个相等的下标

/**
	 * 第一个与查找值相等的值
	 * 设置两个指针分别指向数组收尾
	 * 获取数组中间值,跟value做对比,如果小于中间值说明在中间值左侧,反之在右侧
	 * @param items
	 * @param value 要查找的数
	 * @return
	 */
	public static int lSearch(int [] items,int value){
		//指定指针分别指向数组首位
		int low = 0;
		int high = items.length-1;
		//低位不能大于高位
		while (low <= high){
			//获取中间值:类似于(low+high)/2
			int mid = low + ((high-low) >> 1);
			//如果中间值大于等于value则将最高值设为中间值-1
			//要取第一个相等的,,所以相等的情况还要继续往前查找
			if (items[mid] >= value){
				high = mid-1;
			}else {
				low = mid+1;
			}
		}
		//如果要找第一个大于等于的值:去掉 items[high] == value就可以
		if (low < items.length && items[low] == value){
			return low;
		}
		return -1;
	}

变种2:查找最后一个相等的下标

/**
	 * 查找最后一个相等的下标
	 * @param items
	 * @param value
	 * @return
	 */
	public static int rSearch(int [] items,int value){
		int low = 0;
		int high = items.length-1;
		while (low <= high){
			int mid = low + ((high - low) >> 1);
			//如果小于等于说明在右边,将最小值设为mid+1
			if (items[mid] <= value){
				low = mid + 1;
			}else {
				high = mid - 1;
			}
		}
		//如果要找最后一个小于等于的值:去掉 items[high] == value就可以
		if (high <= items.length && items[high] == value){
			return high;
		}
		return -1;
	}

变种3:查找最后一个小于等于的值,查找第一个大于等于的值

上面两个变种的最后一行注释

缺点:

  1. 二分查找是基于下标操作的,只适用于数组,如果是链表这种复杂度会变高
  2. 数组内数据必须有序
  3. 数组的内存必须是连续的,对内存要求比较高
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值