经典数据查询--二分查找(简单有序数组的二分查找)

引言

    博主最近正在学习算法相关知识,是一个初学者。从初学者的角度来进行了解什么是二分查找。

    二分查找就相当于猜数游戏。我们小时候经常玩的猜数游戏中所用的方法一样。在这个游戏里,一个朋友会让你猜他正想的一个1至100之间的数。当你猜了一个数后,他会告诉你三种选择中的一个:你猜的比他想的大,或小,或猜中了。

    所以为了能用最小的次数猜中,必须从50开始猜。如果他说你猜的太小,则推出哪个数在51至100之间,所以下一次猜75(50至100的一半)。但如果他说你猜的50有些大,则推出哪个数在1至49之间,下一次猜25。

    每猜一次就会将可能的值划分成两部分。最后范围会缩小到一个数字那么大,就是答案。

    以往都是从1开始,然后是2,3,4等等,一个个进行线性查找。而在二分查找中,每猜测一次都是将可能的值划分成两部分,因此猜测的次数大大减少。

    以下就是线性和二次查找:

/**
 * 有序数组数据查找 
 * @author whmAdmin
 *
 */
public class Search {

	private long[] a;	// 查找的数组
	private int nElems; // 数组元素个数
	
	/**
	 * 线性查找  时间复杂度O(N)
	 * @param searchKey	查找的数
	 * @return 存在true 不存在 false
	 */
	public boolean linearSearch(long searchKey) {
		int j;
		// 找到停止循环
		for (j = 0; j < nElems; j++) {
			if(a[j] == searchKey) {
				break;
			}
		}
		// 判断下坐标
		if(j == nElems) {
			return false;
		}else {
			return true;
		}
	}
	
	/**
	 * 二分查找有序数组 时间复杂度O(logN)
	 * @param searchKey
	 * @return
	 */
	public int binarySearch(long searchKey) {
		// 下坐标
		int lowerBound = 0;
		// 上坐标
		int upperBound = nElems - 1;
		// 中间坐标
		int curIn;
		
		while(true) {
			// 获取中间坐标
			curIn = (lowerBound + upperBound) /2;
			// 中间坐标位置元素与查找元素相等
			if(a[curIn] == searchKey) {
				// 返回下坐标
				return curIn;
			// 上坐标大于下坐标
			} else if(lowerBound > upperBound){
				// 返回总位置数
				return nElems;
			} else{
				// 中间位置元素小于查找元素
				if(a[curIn] < searchKey) {
					// 下坐标等于中间坐标后一位坐标上
					lowerBound = curIn+1;
				}else {
					// 否则 上坐标等于中间坐标前一位坐标上
					upperBound = curIn -1;
				}
			}
		}
	}
	
}
以上二分查找只适合有序数组进行查找,没有考虑重复值等其他因素。便宜初学者了解什么是二分查找。

你可能感兴趣的:(算法小结)