算法02 - 二分查找 - 与冒泡排序及选择排序的结合

今天呢,进行了二分查找的学习,待会结合昨天的排序方法写两个小栗子。
现在呢,先跟大家介绍一下什么是二分查找吧。

二分查找

什么是二分查找?

二分查找(Binary Search)是一种高效的搜索算法,专门用于在已排序的数组或列表中查找目标值的位置。它的基本思想是通过将搜索范围不断折半来缩小查找范围,从而快速找到目标值。

二分查找的基本思想:

  • 在一个有序的数组中,选择中间元素作为比较对象。
  • 如果中间元素等于目标值,则查找成功,返回该元素的位置。
  • 如果中间元素大于目标值,则目标值一定在左半部分,继续在左半部分进行二分查找。
  • 如果中间元素小于目标值,则目标值一定在右半部分,继续在右半部分进行二分查找。
  • 重复上述过程,直到找到目标值或搜索范围为空(此时目标值不在数组中)。

二分查找的步骤:

  1. 初始范围:设定数组的起始位置 left 和结束位置 right
  2. 计算中间位置mid = (left + right) / 2。/
  3. 比较
    • 如果 arr[mid] 等于目标值 num,返回 mid 作为目标值的位置。
    • 如果 arr[mid] 大于目标值 num,将right设为 mid - 1,继续在左半部分查找。
    • 如果 arr[mid] 小于目标值 num,将left设为 mid + 1,继续在右半部分查找。
  4. 循环或递归:重复上述步骤,直到 left > right(表示目标值不在数组中),则返回 -1 表示查找失败。

老规矩,上我的小栗子。

/*
二分查找/折半查找
    前提是数组有序
    特点是每一次查找完成,会舍去一半元素

思路分析
    1、定义两个指针,指向数组第一个和最后一个索引位置
    2、循环查找,min小于等max则继续(三个指针可能重叠的)
    3、每次循环进来,重新计算中间指针
    4、判断情况1:如果mid指向的元素就是num,则返回mid
    5、判断情况2:如果要查找的元素,在左半边,舍弃max重新计算
    6、判断情况3:如果要查找的元素,在右半边,舍弃min重新计算
    7、循环结束没有找到,则代表不存在,返回-1
 */
public class Demo1 {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};

        System.out.println(binarySearch(arr, 1));
        System.out.println(binarySearch(arr, 2));
        System.out.println(binarySearch(arr, 3));
        System.out.println(binarySearch(arr, 4));
        System.out.println(binarySearch(arr, 5));
        System.out.println(binarySearch(arr, 6));
        System.out.println(binarySearch(arr, 7));
        System.out.println(binarySearch(arr, 8));
        System.out.println(binarySearch(arr, 9));
        System.out.println(binarySearch(arr, 10));
    }

    //二分查找
    private static int binarySearch(int[] arr, int num) {
        int left = 0;
        int right = arr.length - 1;
        int mid = (left + right) / 2;
        while (left <= right) {
            if (arr[mid] == num) {
                return mid;
            } else if (arr[mid] > num) {
                right = mid - 1;
                mid = (left + right) / 2;
            } else {
                left = mid + 1;
                mid = (left + right) / 2;
            }
        }
        return -1;
    }
}
二分查找的特点:
  • 时间复杂度:二分查找的时间复杂度为 O(log⁡n)O(\log n)O(logn),其中n是数组的长度。因为每次查找将搜索范围缩小一半,查找效率非常高。
  • 空间复杂度:空间复杂度为 O(1)O(1)O(1),因为只需要常量级别的额外空间来存储变量(低位、位、中间位)。
  • 要求:二分查找仅适用于已排序的数组或列表,如果数组未排序,需要先进行排序操作。
二分查找的优缺点:
  • 优点
    • 时间复杂度较低,适用于在大规模有序数组中进行快速查找。
    • 实现简单且高效。
  • 缺点
    • 只能应用于有序数组或列表。
    • 数组需要支持随机访问,适合用于静态数据集,对于动态插入、删除的数据集不太合适。

至此,二分查找就结束咯,
But,今天的内容还有一个小扩展
那就是
就是
运用冒泡排序和选择排序以及二分查找,完成两个数组的排序以及查找。

/*
    定义一个乱序的整型数组,对其进行排序并查找相应元素的对应索引值
 */
public class Demo2 {
    public static void main(String[] args) {
        //1.定义一个乱序的整型数组
        int[] arr = {11, 25, 13, 60, 88, 63};
        //3.调用方法进行冒泡排序
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));

        //5.调用查找方法进行查找指定元素的索引值
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您要查找的数字");
        int num =sc.nextInt();
        //输出结果
        int search = binarySearch(arr, num);
        System.out.println(search);

    }

    //2.编写一个冒泡排序方法
    public static void bubbleSort(int[] arr) {
        //i为循环多少轮
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    //进行交换顺序
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    //4.编写一个二分查找法
    public static int binarySearch(int[] arr, int num) {
        int left = 0;
        int right = arr.length - 1;
        int mid = (left + right) / 2;
        while(left <= right) {
            if (arr[mid] == num) {
                System.out.println("您要查找的数字索引是:");
                return mid;
            } else if (arr[mid] > num) {
                right = mid - 1;
                mid = (left + right) / 2;
            } else {
                left = mid + 1;
                mid = (left + right) / 2;
            }
        }
        System.out.println("很抱歉,没能找到您要查找的数字索引.");
        return -1;//没找到该元素的索引
    }
}

下面是将选择排序和二分查找相互结合的一个小栗子

/*
     定义一个乱序的整型数组,用选择排序对它进行正序处理,并定义方法进行元素查找
 */
public class Demo3 {
    public static void main(String[] args) {
        //定义一个整型数组
        int[] arr = {11, 25, 13, 60, 88, 63};

        //3.调用选择排序方法进行排序
        selectionSort(arr);
        System.out.println(Arrays.toString(arr));

        //5.调用二分查找法查询元素的索引值
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入您要查找的数字:");
        int num = sc.nextInt();
        int Search = binarySearch(arr, num);
        System.out.println(Search);
    }

    public static void selectionSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[i] > arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
    //4.定义一个二分查找的方法
    public static int binarySearch(int[] arr, int num) {
        int left = 0;
        int right = arr.length - 1;
        int mid = (left + right) / 2;
        while(left <= right) {
            if (arr[mid] == num) {
                System.out.println("您要查找的数字索引是:");
                return mid;
            } else if (arr[mid] > num) {
                right = mid - 1;
                mid = (left + right) / 2;
            } else {
                left = mid + 1;
                mid = (left + right) / 2;
            }
        }
        System.out.println("很抱歉,没能找到您要查找的数字索引.");
        return -1;//没找到该元素的索引
    }
}

以上呢,就是简单的两个小栗子,大家像我一样初学的可以试着写一下,练练手。希望咱们各位能够早日成为大牛,然后顶峰相见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值