东陆之滇

爱是永恒,不可休

导航

二分搜索算法

二分搜索BinarySearch的 "来龙去脉"

二分搜索用于检索某个key是否在已排好序的序列中,我们还记得上编程语言的基础课程:猜字游戏吗?

猜字游戏第一版:
程序预先选取一个数字作为猜想的目标;
用户键盘输入自己猜想的数字;
如果不相等则提示错误;
如果猜对了则游戏终止。

这个游戏猜想效率是很低的。因为这个笨拙的游戏规则只会告诉你是对的还是错误的!!!然后你得进行下一次的瞎猜...

猜字游戏第二版:
程序预先选取一个数字(假设是40)作为猜想的目标;
用户键盘输入自己猜想的数字(假设是5);
如果不相等则提示错误,并且有内容:您猜的太小了;
然后用户输入20,还是提示错误:您猜的太小了;
用户再试探,输入50,提示错误:您猜的太大了;
用户输入40(假设运气好),提示正确,结束游戏。
第二版的游戏相比第一版增加了游戏提示,这个提示有利于用户缩小下一次猜想的数字的大概范围。

我们的二分搜索就可以认为来自这个猜想,思路是:
在有序数组中查找关匹配键字的元素。
获取最大索引 hi、最小索引 lo;
找到中间索引 mid = (hi + lo) / 2;
关键字key去和中间索引值比较arr[mid];
这里的关键字key就类似我们猜字游戏中的40;
如果如果中间索引值arr[mid] > key,则表明key在中间索引的左边,类似于猜字游戏中用户猜的数字大了,需要往小的方向猜。
如果中间索引值arr[mid] < key,则表名key在中间索引的右边,猜的数字比较小,需要往大的方向猜。


package org.byron4j.dsaa.basic;

/**
 * 二分检索--用于检索已排好序的序列
 * @author BYRON.Y.Y
 *
 */
public class BinarySerach {
	
	
	/**
	 * 在有序数组sortedArr中,检索是否存在key,存在则返回索引位置index,否则返回-1
	 * @param sortedArr
	 * @param key
	 * @return
	 */
	public static int index(int[] sortedArr, int key) {
		
		int lo = 0;//低位索引值
		
		int hi = sortedArr.length - 1;//高位索引值
		
		int mid = (hi + lo) / 2;//中间索引值
		
		while( hi >= lo ) {
			if( sortedArr[mid] > key ) {
				//中间值大于key,则说明key在中间值前面,高位减一
				hi = mid - 1;
			}else if( sortedArr[mid] < key ){
				//中间值小于key,则说明key在中间值后面,低位加一
				lo = mid + 1;
			}else {
				return mid;
			}
			//重新计算中间索引位置
			mid = (hi + lo) / 2;
		}
		
		return -1;
		
	}
	public static void main(String[] args) {
		int[] arr = {1, 2, 3, 4, 5, 6};
		System.out.println(index(arr, 1));//0
		System.out.println(index(arr, 2));//1
		System.out.println(index(arr, 3));
		System.out.println(index(arr, 4));
		System.out.println(index(arr, 5));
		System.out.println(index(arr, 6));//5
		System.out.println(index(arr, 7));//-1
		System.out.println(index(arr, -1));//-1
	}
	
	
}


运行结果如下:

0
1
2
3
4
5
-1
-1

posted on 2018-06-27 16:25  东陆之滇  阅读(107)  评论(0编辑  收藏  举报