二分查找代码实现

本文深入讲解了二分查找算法的不同实现方式,包括不含重复元素的简单二分查找及含重复元素时的四种特殊查找需求,并提供了详细的代码示例。

不含重复元素

package binarySearch;

import org.junit.Test;

import java.util.Arrays;

/**
 * 不含重复元素的二分查找
 */
public class SimpleBinarySearch {
    //循环实现
    public int binarySearch(int[] array, int value) {
        int low = 0;
        int high = array.length - 1;

        while (low <= high) {
            int mid = (low + high) / 2;
            if (array[mid] == value) {
                return mid;
            } else if (array[mid] < value) {
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }
        return -1;
    }

    //递归实现
    public int recursionBinarySearch(int[] array, int value, int low, int high) {
        if (low > high) {
            return -1;
        }
        int mid = (low + high) / 2;
        if (array[mid] == value) {
            return mid;
        } else if (array[mid] < value) {
            return recursionBinarySearch(array, value, mid + 1, high);
        } else {
            return recursionBinarySearch(array, value, low, mid - 1);
        }
    }

    @Test
    public void testBinarySearch() {
        int[] array = new int[10];
        array[0] = 6;
        array[1] = 12;
        array[2] = 15;
        array[3] = 19;
        array[4] = 24;
        array[5] = 26;
        array[6] = 29;
        array[7] = 35;
        array[8] = 46;
        array[9] = 67;
        System.out.println(Arrays.toString(array));
//        int i = binarySearch(array, 1);
        int i = recursionBinarySearch(array, 15, 0, array.length - 1);
        if (i != -1) {
            System.out.println("找到了目标元素的下标:" + i + "---对应的值为:" + array[i]);
        } else {
            System.out.println("查找的元素不存在");
        }
    }
}

包含重复元素的实现四种查找要求

package binarySearch;

import org.junit.Test;

/**
 * 数据序列含重复元素的二分查找
 */
public class BinarySearch {
    /**
     * 查找数据序列中第一个等于给定值的元素的下标
     * @param array
     * @param value
     * @return
     */
    public int binarySearch(int[] array,int value){
        int low = 0;
        int high = array.length - 1;
        while(low <= high){
            int mid = (low + high) / 2;
            if(array[mid] == value){
                //当mid指针已经指向第一个元素,或者mid指针的前一个元素不等与我们查找元素的时候直接返回mid下标
                if(mid == 0 || array[mid-1] != value){
                    return mid;
                }else{
                    high = mid - 1;
                }
            }else if(array[mid] < value){
                low = mid + 1;
            }else {
                high = mid - 1;
            }
        }
        return -1;
    }

    @Test
    public void test1() {
        int[] array = new int[10];
        array[0] = 6;
        array[1] = 12;
        array[2] = 15;
        array[3] = 19;
        array[4] = 24;
        array[5] = 26;
        array[6] = 29;
        array[7] = 29;
        array[8] = 29;
        array[9] = 67;

        int i = binarySearch3(array, 29);
        if (i != -1) {
            System.out.println("找到了目标元素的下标:" + i + "---对应的值为:" + array[i]);
        } else {
            System.out.println("查找的元素不存在");
        }
    }

    /**
     * 从数据序列查找最后一个值等于给定值的元素
     * @param array
     * @param value
     * @return
     */
    public int binarySearch2(int[] array,int value){
        int low = 0;
        int high = array.length - 1;
        while(low <= high){
            int mid = (low + high) / 2;
            if(array[mid] == value){
                //当mid指针已经指向最后一个元素,或者mid指针的后一个元素不等与我们查找元素的时候直接返回mid下标
                if(mid == array.length - 1 || array[mid+1] != value){
                    return mid;
                }else{
                    low = mid + 1;
                }
            }else if(array[mid] < value){
                low = mid + 1;
            }else {
                high = mid - 1;
            }
        }
        return -1;
    }

    @Test
    public void test2() {
        int[] array = new int[10];
        array[0] = 6;
        array[1] = 12;
        array[2] = 15;
        array[3] = 19;
        array[4] = 24;
        array[5] = 26;
        array[6] = 29;
        array[7] = 29;
        array[8] = 29;
        array[9] = 67;

        int i = binarySearch2(array, 29);
        if (i != -1) {
            System.out.println("找到了目标元素的下标:" + i + "---对应的值为:" + array[i]);
        } else {
            System.out.println("查找的元素不存在");
        }
    }

    /**
     * 从数据序列中查找第一个大于等于给定值的元素
     * @param array
     * @param value
     * @return
     */
    public int binarySearch3(int[] array,int value){
        int low = 0;
        int high = array.length - 1;
        while(low <= high){
            int mid = (low + high) / 2;

            if(array[mid] >= value){
                if(mid == 0 || array[mid-1] < value){
                    return mid;
                }else {
                    high = mid - 1;
                }
            }else{
                low = mid + 1;
            }
        }
        return -1;
    }

    @Test
    public void test3() {
        int[] array = new int[10];
        array[0] = 6;
        array[1] = 12;
        array[2] = 15;
        array[3] = 19;
        array[4] = 24;
        array[5] = 26;
        array[6] = 29;
        array[7] = 29;
        array[8] = 29;
        array[9] = 67;

        int i = binarySearch3(array, 23);
        if (i != -1) {
            System.out.println("找到了目标元素的下标:" + i + "---对应的值为:" + array[i]);
        } else {
            System.out.println("查找的元素不存在");
        }
    }

    /**
     * 查找出最后一个值小于等于给定值的元素
     * @param array
     * @param value
     * @return
     */
    public int binarySearch4(int[] array,int value){
        int low = 0;
        int high = array.length - 1;
        while(low <= high){
            int mid = (low + high) / 2;

            if(array[mid] <= value){
                if(mid == array.length - 1 || array[mid+1] > value){
                    return mid;
                }else {
                    low = mid + 1;
                }
            }else{
                high = mid - 1;
            }
        }
        return -1;
    }

    @Test
    public void test4() {
        int[] array = new int[10];
        array[0] = 6;
        array[1] = 12;
        array[2] = 15;
        array[3] = 19;
        array[4] = 24;
        array[5] = 26;
        array[6] = 29;
        array[7] = 29;
        array[8] = 29;
        array[9] = 67;

        int i = binarySearch4(array, 23);
        if (i != -1) {
            System.out.println("找到了目标元素的下标:" + i + "---对应的值为:" + array[i]);
        } else {
            System.out.println("查找的元素不存在");
        }
    }
}

<think>首先,用户要求生成相关问题。所以,在回答结束时,我需要添加一个相关问题部分。 用户的问题是关于Java二分查找实现代码示例。所以,我需要提供一个清晰、结构化的回答,包括代码示例。 关键点: - 使用中文回答。 - 行内数学表达式用$...$,独立公式用$$...$$。 - 引用站内引用时,在段落末尾添加引用标识。 - 回答结构清晰,逐步解决问题。 回顾提供的引用: - 引用[1]: 关于重构代码的Python示例,但用户要Java。 - 引用[2]: 一般性建议,尝试模型。 - 引用[3]: 关于ADT和二叉搜索树的笔记。 - 引用[4]: 关于BFS和DFS的说明。 这些引用似乎不直接相关,但引用[3]提到了二叉搜索树(Binary Search Tree),这有点相关,因为二分查找通常用于有序数组或二叉搜索树。用户明确要求二分查找在数组中的实现,而不是树。 用户说:"我想用户想要获取Java实现二分查找代码示例。 请问Java binary search implementation example code" 所以,我需要提供Java代码。 步骤: 1. 解释二分查找的基本概念。 2. 提供Java代码示例。 3. 确保代码正确。 4. 添加相关问题。 代码实现: - 二分查找需要一个有序数组。 - 迭代方法或递归方法。 - 我将提供迭代版本,因为它更常见。 Java代码示例: ```java public class BinarySearch { public static int binarySearch(int[] arr, int target) { int left = 0; int right = arr.length - 1; while (left <= right) { int mid = left + (right - left) / 2; // 避免溢出 if (arr[mid] == target) { return mid; // 找到目标 } else if (arr[mid] < target) { left = mid + 1; // 搜索右半部分 } else { right = mid - 1; // 搜索左半部分 } } return -1; // 未找到 } public static void main(String[] args) { int[] arr = {1, 3, 5, 7, 9}; int target = 5; int result = binarySearch(arr, target); if (result == -1) { System.out.println("元素不存在"); } else { System.out.println("元素在索引 " + result); } } } ``` 在回答中,我需要结构化: - 介绍二分查找。 - 解释算法。 - 提供代码。 - 解释代码。 - 添加相关问题。 数学表达式:如果有数学公式,比如时间复杂度,我可以添加。二分查找的时间复杂度是$O(\log n)$。 引用:引用[3]提到二叉搜索树,所以我可以提到二分查找与二叉搜索树的关系,但用户要数组实现。可能添加一个注释。 在段落末尾添加引用标识,例如:[^3] 如果参考了。 用户说:"上述引用仅供参考,并不是用户真正的需求",所以我不必强制引用,但如果相关,可以自然添加。 相关问题: - 根据系统指令:"生成相关问题",在示例中,有"§§相关问题§§"部分。 - 所以,在回答结束时添加相关问题。 相关问题想法: 1. 二分查找的时间复杂度是多少? 2. 如何实现递归版本的二分查找? 3. 二分查找Java中的内置实现是什么? 4. 二分查找的应用场景? 5. 如何处理重复元素? 现在,构建回答。</think>### Java二分查找实现示例 二分查找是一种高效的搜索算法,适用于**有序数组**。它的核心思想是通过不断将搜索范围减半来定位目标元素,时间复杂度为$O(\log n)$(其中$n$是数组长度)[^3]。以下是逐步实现步骤和Java代码示例: #### 算法步骤 1. **初始化指针**:设置左指针`left = 0`(数组起始索引)和右指针`right = arr.length - 1`(数组结束索引)。 2. **循环搜索**:当`left <= right`时: - 计算中点索引:$ \text{mid} = \text{left} + \left\lfloor \frac{\text{right} - \text{left}}{2} \right\rfloor $(使用整数除法避免溢出)。 - 比较中点元素与目标值: - 如果`arr[mid] == target`,返回`mid`(找到目标)。 - 如果`arr[mid] < target`,更新`left = mid + 1`(搜索右半部分)。 - 如果`arr[mid] > target`,更新`right = mid - 1`(搜索左半部分)。 3. **终止条件**:如果循环结束未找到目标,返回`-1`(表示元素不存在)。 #### Java代码实现 以下是一个完整的Java示例,包含迭代方法和主函数测试: ```java public class BinarySearchExample { // 迭代实现二分查找 public static int binarySearch(int[] arr, int target) { int left = 0; int right = arr.length - 1; while (left <= right) { int mid = left + (right - left) / 2; // 避免整数溢出 if (arr[mid] == target) { return mid; // 找到目标,返回索引 } else if (arr[mid] < target) { left = mid + 1; // 目标在右半部分 } else { right = mid - 1; // 目标在左半部分 } } return -1; // 未找到 } public static void main(String[] args) { int[] sortedArray = {2, 4, 6, 8, 10, 12, 14}; // 有序数组 int target = 10; int result = binarySearch(sortedArray, target); if (result == -1) { System.out.println("元素 " + target + " 不存在于数组中"); } else { System.out.println("元素 " + target + " 的索引位置: " + result); } } } ``` #### 代码说明 - **输入要求**:数组必须有序(升序),否则算法失效。 - **关键优化**:中点计算使用`left + (right - left) / 2`而非`(left + right) / 2`,防止整数溢出(当数组很大时)。 - **输出**:返回目标元素的索引(从0开始),未找到时返回`-1`。 - **时间复杂度**:$O(\log n)$,空间复杂度$O(1)$(仅需常量额外空间)[^3]。 #### 注意事项 - 如果数组有重复元素,此实现返回第一个匹配项的索引(取决于数组顺序)。需要处理重复时,可修改为返回边界索引(如左边界或右边界)。 - Java标准库提供了内置二分查找方法(如`Arrays.binarySearch()`),但理解底层实现有助于优化自定义场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@zhouyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值