一、介绍
二分查找又称折半查找、二分搜索、折半搜索等,是一种在静态查找表中查找特定元素的算法。
所谓静态查找表,即只能对表内的元素做查找和读取操作,不允许插入或删除元素。
使用二分查找算法,必须保证查找表中存放的是有序序列(升序或者降序)。换句话说,存储无序序列的静态查找表,除非先对数据进行排序,否则不能使用二分查找算法。
二、实现思路
二分查找和顺序查找的对比:
通过上图比较可知二分查找元素的步骤要比顺序查找的步骤少了7步
所谓二分查找就是从有序列表长度的一半(n/2)开始进行查找,如果要查找的值大于中间值,则把左边的指针向右移动m+1个单位(m代表每次中间值的下标),相反则把右边的指针向左移动m-1个单位。
具体实现代码:
public class binarysearch {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6,7,8};
System.out.println(bs(arr,4));
}
//二分查找
public static int bs(int[] a,int target){
int i=0,j=a.length-1;//设置指针和初值
while(i<=j){//范围内有东西
int m = (i+j)>>>1;
if(target<a[m]){//目标在左边
j=m-1;
}else if(target>a[m]){//目标在右边
i=m+1;
}else{//目标相等,返回索引
return m;
}
}
//没找到返回-1
return -1;
}
}
注意:这里的中间值m为什么不能写成(i+j)/2呢?这么写不是更容易理解吗?最开始我也是这么想的,哈哈哈。but,这样写有个问题,就是当它计算出来超过了整型的范围就会出现负数,因为int数据类型是32位带符号的二进制补码整数。下标哪里有负的,肯定是没有的,解决办法就是写成(i+j)>>>1,它的意思就是将这个数的二进制整体想右移动一个单位,比如(8)00001000移动完之后就是(4)00000100,刚好就是一半,所以这里要注意到。