二分查找

来源:互联网 发布:邱少云违背生理学知乎 编辑:程序博客网 时间:2024/06/06 00:43

      当一个数组需要用到查找方法时,可以遍历整个数组,找到相等的值返回下标,这种方法效率比较低。如果这个数组是有序的,我们可以使用二分查找(折半查找)。二分查找是将数组不断的分成两段,判断我们要找的数据与中值是否相等。

     如果我们有这样一个数组 int [] arr={0,10,20,30,40,50,60,70},使用二分查找找到60;

    我们首先要找到中值30与60对比,30与60 是不等的,并且60比30 大,所以我们在40与70之间的中值50 与60相比,50与60也是不等的,并且60比50大,所以,让60与70之间的中值60 与60是相等的,所以返回中值60的下标,代码如下:

   

public static int binarySearch(int[] arr,int key){int max,min,mid;min=0;max=arr.length-1;mid=(max+min)>>1; //右移一位相当于除2运算。while(arr[mid]!=key){              //当中值与要找的数据不相等,进入循环if (key>arr[mid]) {        //如果数据比中值大min=mid+1;         //让最小下标放在中值后面,找较大的另一半数据}else if(key<arr[mid]){     //如果数据比中值小max=mid-1;         //让最大下标放在中值前面,找较小的另一半数据}if (max<min) {             //当最大下标比最小下标小时,说明数据不存在return -1;}mid=(max+min)>>1;}return mid;                       //当中值与要找的数据相等,说明数据找到,返回中值的下标。}
     所以我们也可以换一种方式写这段代码,当最小小标小于等于最大下标,说明数据存在,进入循环折半查找,反之,说明数据不存在,循环结束返回-1.

   

        public static int binarySearch(int[] arr,int key){int max,min,mid;min=0;max=arr.length-1;mid=(max+min)>>1;while(min<=max){mid=(max+min)>>1;if (key>arr[mid]) {min=mid+1;}else if(key<arr[mid]){max=mid-1;}elsereturn mid;}return -1;}
     那么,如果给定一个有序的数组,如果往数组中插入一个元素还保证数组有序,那么元素的脚标位改如何获取?   

     当一个数组初始化完毕,数组的个数是固定的,没有办法在数组里面增加元素,但是我们是可以获取它的脚标位的。如果我们要插入的这个元素数组里面没有,我们要找到这个元素的插入点我们知道,当max<min 的时候确定了元素其实是不存在的,因为max移到了min 的前面还是没找到,此时min所指的位置其实就是插入点,因为min刚好大一位。所以我们让没找到元素时的返回值为min即可。所以上述代码,把return -1改成return min就可以解决这个问题了。

    Java也是有二分查找方法的,Array.binarySearch();是Java自带的二分查找方法,如果我们调用这个方法:

       能够找到数据的下标为6,如果数据不存在呢?

        我们看到,当数据不存在时,它的返回值成了负数,这个负数其实是这个数据的插入点减一。55在数组之中的插入点应该是6,但这个数据其实是不存在的,所以用负数表示不存在的含义,也就是-6,但是我们为了解决和0冲突的问题,所以就让插入点减一。(试想如果我们要查找-1,插入点应该是0,但是如果我们不减去一,那就和零冲突了)。总而言之,Java真是一个贴心的存在啊,,虽然Java给我们提供了方法,但是必要的知识我们还是应该知道的。


1 0