算法篇——二分查找

目录

二分查找

1.什么是二分查找?为什么要用二分查找?

2.二分查找的适用情况

3.二分查找的实现原理简要描述

4.二分查找图示

5.二分查找的代码实现

二分查找

1.什么是二分查找?为什么要用二分查找?

二分查找也叫做折半查找。

相当于将容器反复折成一半,然后查找当中的元素,对于数据比较多的时候,这样的查找形式相较于从头遍历一个一个查找效率更高。

2.二分查找的适用情况

数组中的元素必须是有大小顺序的,即从小到大,或者从大到小。同时数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的。

如果是无序的,也可以先进行排序。但是排序之后,会改变原有数据的顺序,查找出来元素位置跟原来的元素可能是不一样的,所以排序之后再查找只能判断当前数据是否在容器当中,返回的索引无实际的意义。

3.二分查找的实现原理简要描述

假设要查找的数据在数组中存在,则将要查找的数据和数组中间节点的元素进行大小比较,比较完之后有以下几种情况:

  • 要查找的数据和中间节点的数据相等:说明找到了

  • 要查找的数据比中间节点的数据小:说明要查找的数字在中间节点左边,将容器折半继续查找

  • 要查找的数据比中间节点的数据大:说明要查找的数字在中间节点右边,将容器折半继续查找

4.二分查找图示

自己做了一个简陋的示意图。

我们定义 target 是在一个在左闭右闭的区间里,也就是[min, max]

5.二分查找的代码实现

public class Demo {
    public static void main(String[] args) {
        //需求:定义一个方法binarySearch利用二分查找,查询某个元素在数组中的索引
        int[] arr = {1, 4, 9, 16, 16, 19, 33};
        System.out.println(binarySearch(arr, 19));
    }

    public static int binarySearch(int[] arr, int number){
        //1.定义两个变量记录要查找的索引的范围
        int min = 0;
        int max = arr.length - 1;

        //2.利用循环不断的去找要查找的数据。循环的两个结束条件:1、找到了数据,返回-1;2、没有找到数据,min > max,返回下标
        while(true){
            if(min > max){
                return -1;
            }
            //3.找到min和max的中间位置
            int mid = (min + max) / 2;
            //4.拿着mid指向的元素跟要查找的元素进行比较
            if(arr[mid] > number){
                //number在mid的左边
                //min不变,max = mid - 1;
                max = mid - 1;
            }else if(arr[mid] < number){
                //number在mid的右边
                //max不变,min = mid + 1;
                min = mid + 1;
            }else{
                //number跟mid指向的元素一样
                //找到了
                return mid;
            }
        }
    }
}

6.刷一道Leetcode原题

704. 二分查找 - 力扣(LeetCode)

这里参考代码随想录的解答:

对于左闭右闭区间:

class Solution {
    public int search(int[] nums, int target) {
        // 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算
        if (target < nums[0] || target > nums[nums.length - 1]) {
            return -1;
        }
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target)
                return mid;
            else if (nums[mid] < target)
                left = mid + 1;
            else if (nums[mid] > target)
                right = mid - 1;
        }
        return -1;
    }
}

对于左闭右开区间:

class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length;
        while (left < right) {
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target)
                return mid;
            else if (nums[mid] < target)
                left = mid + 1;
            else if (nums[mid] > target)
                right = mid;
        }
        return -1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值