当前位置:   article > 正文

Java 与查找算法(2)二分查找_java二分搜索

java二分搜索

一、二分查找

二分查找,也称折半查找,是一种常见的查找算法。它的思想是将有序数组分成两部分,取中间位置的值与目标值进行比较,如果相等则返回该位置,如果目标值小于中间值,则在左半部分继续查找,否则在右半部分继续查找,直到找到目标值或者数组被遍历完。

二分查找的时间复杂度为 O(log n),是一种高效的查找算法。但是它要求数组必须是有序的,因此在某些情况下,为了使用二分查找,需要先对数组进行排序。

二分查找的实现有两种方式:

  1. 递归实现

递归实现二分查找的核心思想是将数组不断地分成两半,直到找到目标值或者数组被遍历完。具体实现可以参考以下代码:

int binarySearchRecursive(int arr[], int left, int right, int target) {
    if (left > right) {
        return -1;  // 没有找到目标值,返回 -1
    }
    int mid = left + (right - left) / 2;  // 计算中间位置
    if (arr[mid] == target) {
        return mid;  // 找到目标值,返回位置
    } else if (arr[mid] > target) {
        return binarySearchRecursive(arr, left, mid - 1, target);  // 在左半部分继续查找
    } else {
        return binarySearchRecursive(arr, mid + 1, right, target);  // 在右半部分继续查找
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  1. 非递归实现

非递归实现二分查找的核心思想是使用循环不断地将数组分成两半,直到找到目标值或者数组被遍历完。具体实现可以参考以下代码:

int binarySearchIterative(int arr[], int left, int right, int target) {
    while (left <= right) {
        int mid = left + (right - left) / 2;  // 计算中间位置
        if (arr[mid] == target) {
            return mid;  // 找到目标值,返回位置
        } else if (arr[mid] > target) {
            right = mid - 1;  // 在左半部分继续查找
        } else {
            left = mid + 1;  // 在右半部分继续查找
        }
    }
    return -1;  // 没有找到目标值,返回 -1
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

需要注意的是,二分查找只适用于静态数组,即数组不会频繁地进行插入、删除等操作。如果需要频繁地进行这些操作,可以考虑使用其他数据结构,如平衡二叉树、哈希表等。

二、二分查找的性质

二分查找也称为折半查找,是一种在有序数组中查找特定元素的算法。它具有以下性质:

  1. 二分查找要求数组必须是有序的,如果数组无序,则需要先进行排序操作。

  2. 二分查找的时间复杂度为O(log n),其中n为数组的长度。这是一种非常高效的查找算法,适用于大型数据集。

  3. 二分查找只适用于静态数据集,即数据集不会频繁地插入、删除或修改。如果数据集经常变化,则需要使用其他算法。

  4. 二分查找是一种分治算法,它将问题分成两个子问题进行解决。每次比较都可以将搜索范围缩小一半,直到找到目标元素或搜索范围为空。

  5. 二分查找可以使用递归或迭代的方式实现。递归实现代码简单,但可能会导致栈溢出。迭代实现代码稍微复杂一些,但不会出现栈溢出的问题。

  6. 二分查找只能用于查找单个元素,无法用于查找多个元素。如果需要查找多个元素,可以使用二分查找的变体,如二分查找第一个出现的元素、二分查找最后一个出现的元素、二分查找第一个大于等于目标元素的元素、二分查找最后一个小于等于目标元素的元素等。

三、二分查找的变种

除了基本的二分查找外,还有以下几种常见的二分查找变种:

  1. 查找第一个值等于给定值的元素

在基本的二分查找中,当找到目标元素时就返回。但是,如果数组中存在多个值等于目标元素的元素,则基本的二分查找无法确定哪一个是第一个。因此,需要对基本的二分查找进行修改,使其能够查找第一个值等于给定值的元素。

具体实现方式如下:

  • 如果mid指向的元素等于目标元素,判断mid是否为第一个元素或者mid前一个元素不等于目标元素,如果是,则mid就是第一个值等于给定值的元素;否则,继续在左半部分查找。
  • 如果mid指向的元素大于目标元素,则在左半部分查找。
  • 如果mid指向的元素小于目标元素,则在右半部分查找。
  1. 查找最后一个值等于给定值的元素

与查找第一个值等于给定值的元素类似,查找最后一个值等于给定值的元素也需要对基本的二分查找进行修改。

具体实现方式如下:

  • 如果mid指向的元素等于目标元素,判断mid是否为最后一个元素或者mid后一个元素不等于目标元素,如果是,则mid就是最后一个值等于给定值的元素;否则,继续在右半部分查找。
  • 如果mid指向的元素大于目标元素,则在左半部分查找。
  • 如果mid指向的元素小于目标元素,则在右半部分查找。
  1. 查找第一个大于等于给定值的元素

查找第一个大于等于给定值的元素也需要对基本的二分查找进行修改。

具体实现方式如下:

  • 如果mid指向的元素大于等于目标元素,判断mid是否为第一个元素或者mid前一个元素小于目标元素,如果是,则mid就是第一个大于等于给定值的元素;否则,继续在左半部分查找。
  • 如果mid指向的元素小于目标元素,则在右半部分查找。
  1. 查找最后一个小于等于给定值的元素

查找最后一个小于等于给定值的元素也需要对基本的二分查找进行修改。

具体实现方式如下:

  • 如果mid指向的元素小于等于目标元素,判断mid是否为最后一个元素或者mid后一个元素大于目标元素,如果是,则mid就是最后一个小于等于给定值的元素;否则,继续在右半部分查找。
  • 如果mid指向的元素大于目标元素,则在左半部分查找。

四、二分查找的应用场景

二分查找的应用场景包括但不限于以下几个方面:

  1. 查找有序数组中的元素:二分查找是一种高效的查找算法,适用于有序数组中查找特定元素。例如,在一个数值递增的数组中查找某个数值是否存在。

  2. 查找最大值或最小值:如果一个数组是单调递增或递减的,可以使用二分查找来查找最大值或最小值。例如,在一个升序数组中查找最小值,或者在一个降序数组中查找最大值。

  3. 查找数据范围:如果一个数组中的元素满足某种特定的条件,可以使用二分查找来查找数据范围。例如,在一个有序数组中查找某个数值出现的次数,或者在一个升序数组中查找第一个大于等于某个值的元素。

  4. 查找旋转数组中的元素:如果一个数组是旋转有序的,可以使用二分查找来查找特定元素。例如,在一个旋转有序数组中查找某个数值是否存在。

  5. 查找数学函数的零点:如果一个数学函数是单调递增或递减的,可以使用二分查找来查找函数的零点。例如,在一个单调递增的函数中查找函数f(x)=0的解。

二分查找是一种高效的查找算法,适用于有序数组中查找特定元素或查找数据范围。它的时间复杂度为O(log n),适用于大型数据集。

五、二分查找在spring 中的应用

在Spring框架中,二分查找算法主要应用于Bean的查找和排序。Spring的Bean容器是一个包含多个Bean的容器,当需要获取某个Bean时,Spring框架会根据Bean的名称或类型进行查找。在查找时,Spring框架使用二分查找算法来提高查找效率。

Spring框架中的二分查找算法主要应用于以下两个方面:

  1. Bean的查找:Spring框架中的Bean容器是一个Map类型的容器,其中Bean的名称作为Map的Key,Bean实例作为Map的Value。当需要获取某个Bean时,Spring框架会根据Bean的名称或类型进行查找。在查找时,Spring框架使用二分查找算法来提高查找效率。

  2. Bean的排序:Spring框架中的Bean容器可以对Bean进行排序。在排序时,Spring框架使用二分查找算法来查找插入位置,从而提高排序效率。

Spring框架中的二分查找算法主要应用于Bean的查找和排序,可以提高查找和排序的效率。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/502577
推荐阅读
相关标签
  

闽ICP备14008679号