引言
博主最近正在学习算法相关知识,是一个初学者。从初学者的角度来进行了解什么是二分查找。
二分查找就相当于猜数游戏。我们小时候经常玩的猜数游戏中所用的方法一样。在这个游戏里,一个朋友会让你猜他正想的一个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;
}
}
}
}
}
以上二分查找只适合有序数组进行查找,没有考虑重复值等其他因素。便宜初学者了解什么是二分查找。