用java写一个二分法的demo

package 算法类;

import java.util.Arrays;
// 先把整一个列表算作一个开始和结束,当mid等于target的时候结束或者mid重复出现俩次的时候结束,
// 当arr[mid]大于target的时候start不变,start-end 左对半分,end为mid-1
// 当arr[mid]小于target的时候end不变,start-end 右对半分,start为mid+1
/**
 * 二分法(Binary Search)是一种常用的搜索算法,通常用于在有序数组中查找特定元素的位置。它通过将待搜索区间不断二分,缩小搜索范围,直到找到目标元素或确定目标元素不存在。
 * 二分法的基本思想是先确定搜索范围的起始位置和结束位置,然后取起始位置和结束位置的中间位置的元素进行比较。如果中间位置的元素等于目标元素,则搜索成功并返回该位置。
 * 如果中间位置的元素大于目标元素,则说明目标元素可能在左半部分,将结束位置移到中间位置的前一个位置,再次进行二分查找。
 * 如果中间位置的元素小于目标元素,则说明目标元素可能在右半部分,将起始位置移到中间位置的后一个位置,再次进行二分查找。通过不断缩小搜索范围,最终可以找到目标元素或确定目标元素不存在。
 * 二分法的时间复杂度为 O(logn),其中 n 是数组的大小。由于每次比较都将搜索范围减半,所以二分法是一种高效的搜索算法,特别适用于有序数组。
 * 除了在有序数组中查找特定元素,二分法也可以应用于其他类似问题,例如在有序链表中查找、寻找旋转排序数组中的最小值等。它在算法和数据结构中被广泛使用,并且具有重要的实际应用。
 */
public class 二分法 {
    public static void main(String[] args) {
        int[] arr = {29, 10, 14, 37, 14, 2, 39, 5, 3, 6, 7, 9, 11};
//        Arrays.sort 使用的是快速排序对数组进行排序
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));

//        有了一个有序的列表 就可以用二分法了
        int length = arr.length;

        System.out.println(binary(arr, 37, 0, length - 1,-1));
    }

    public static int binary(int[] arr, int target, int start, int end,int middle) {
//        在 Java 中,当使用整数进行计算时,表达式 (start + end) / 2 可能会导致溢出。
//        当 start 和 end 都是较大的正整数时,它们的和可能会超过 int 数据类型的上限,即 Integer.MAX_VALUE。当和超出 Integer.MAX_VALUE 时,
//        将导致溢出,结果会被截断为负数或其他不正确的值。
//        使用减法溢出保护
        int mid = start + (end-start) /2;
        if(middle==mid) return -1;
        if (arr[mid] == target) {
            System.out.println("找到了" + target);
            return mid;
        } else if (arr[mid] < target) {
            start = mid + 1;
            return binary(arr, target, start, end,mid);
        } else {
            end = mid - 1;
            return binary(arr, target, start, end,mid);
        }
    }
}

为什么传一个middle?

因为在递归的时候,如果上一次的middle和这一次的middle相同,即没有找到该元素

当然也可以不传 使用start>end 条件退出,但是理解起来麻烦一点

猜你喜欢

转载自blog.csdn.net/lfeishumomol/article/details/131615246