用Java实现二分查找

什么是二分查找

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

算法要求

1.必须采用顺序存储结构。
2.必须按关键字大小有序排列。

查找过程

  1. 假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;
  2. 否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。
  3. 重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

代码实现

public class BinarySearch {
    public static void main(String[] args) {
        int[] array = {1,3,5,5,5,6,7,10,20,20,20,30};
        int resultIndex = binarySearch(array,0,array.length-1,20);
        System.out.println("所在下标为:"+resultIndex);

        List resultIndexList = binarySearch2(array,0,array.length-1,5);
        System.out.println("所在下标为"+resultIndexList);
    }

    /**
     * 查找一个值在有序数组中的位置。
     * @param arrays 有序数组
     * @param left 开始位置
     * @param right 结束位置
     * @param findValue 待搜索的值
     * @return 返回查找的值第一次出现的位置
     */
    public static int binarySearch(int[] arrays,int left, int right,int findValue){
        //当left>right时说明已经以查询完毕,未查找到结果,退出
        if(left>right){
            return -1;
        }

        //中间值的下标
        int mid = (left + right) / 2;
        //中间值
        int midVal = arrays[mid];

        //向左递归 ->查找的值比中间值小,说明要查找的值在当前中间值的左边 ,反之亦然
        if(findValue < midVal){
            return binarySearch(arrays, left, mid -1, findValue);
        }else if(findValue > midVal){
            return binarySearch(arrays, mid + 1, right, findValue);
        }else{
            //当findVal == midVal是返回当前下标;
          return mid;
        }
    }

    /**
     * @param arrays 有序数组
     * @param left 开始位置
     * @param right 结束位置
     * @param findValue 待搜索的值
     * @return 待搜索的值的所有位置
     */
    public static List<Integer> binarySearch2(int[] arrays,int left,int right,int findValue){
        //当left>right时说明已经以查询完毕,未查找到结果,退出
        if(left > right){
            return new ArrayList<>();
        }
        //中间值的下标
        int mid = (left + right) / 2;
        //中间值
        int midVal = arrays[mid];

        //向左递归 ->查找的值比中间值小,说明要查找的值在当前中间值的左边 ,反之亦然
        if(findValue < midVal){
            return binarySearch2(arrays, left, mid -1, findValue);
        }else if(findValue > midVal){
            return binarySearch2(arrays, mid + 1, right, findValue);
        }else{
            /**
             * 1.向mid索引左边扫描,将所有符合条件的下标添加到ArrayList中
             * 2.向mid索引右边扫描,将所有符合条件的下标添加到ArrayList中
             * 3.将mid添加到ArrayList中
             * 4.将ArrayList返回
             */
            List<Integer> resultIndexList = new ArrayList<Integer>();
            //1.向mid索引左边扫描,将所有符合条件的下标添加到ArrayList中
            //中间指针左移
            int temp = mid - 1;
            while (true){
                //当指针小于最小index或当前值不等于要查找的值时退出
                if(temp < left || arrays[temp] != findValue){
                    break;
                }
                resultIndexList.add(temp);
                //指针左移
                temp -= 1;
            }
            //3.将mid添加到ArrayList中
            resultIndexList.add(mid);
            //2.向mid索引右边扫描,将所有符合条件的下标添加到ArrayList中
            temp = mid + 1;
            while (true){
                //当指针大于最大index或当前值不等于要查找的值时退出
                if(temp > right || arrays[temp] != findValue){
                    break;
                }
                resultIndexList.add(temp);
                //指针右移
                temp += 1;
            }
            //4.将查找到的所有下标返回
            return resultIndexList;
        }
    }
}

发布了27 篇原创文章 · 获赞 11 · 访问量 4387

猜你喜欢

转载自blog.csdn.net/qq_26020387/article/details/105574815