1. 简述
老规矩,先看概念:baike.baidu.com/item/%E4%BA…
思路:
二分查找的前提是数组必须为有序数组
- 第一步: 先查找数组中间位置 arr[middle],与查找的目标数字 x 是否相等;
- 如果相等则直接返回
- 如果 arr[middle] > x, 则代表 arr[middle] 右侧的数字都大于 x,则下次查找只需要查找 arr[middle]左边的数字
- 如果 arr[middle] < x, 则代表 arr[middle] 左侧的数字都小于 x,则下次查找只需要查找arr[middle]右侧的数字
- 移动左右边界,循环第一步 ...
时间复杂度:经过上面的过程分析可以知道,每次查找都可以排除一半的数字。所以时间复杂度为
2. 实现
package com.omg.sort;
import java.util.Arrays;
/**
* @description: 二分法 - 折半查找
* 介绍:https://baike.baidu.com/item/%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE/10628618?fromtitle=%E6%8A%98%E5%8D%8A%E6%9F%A5%E6%89%BE&fromid=9796273&fr=aladdin
*/
public class Code04_BSExist {
/**
* @description: 查找 sortrdArr 中是否存在 num
* @param sortedArr 有序数组
* @param num 要查找的数据
* @return 存在-true 不存在-false
*/
public static boolean exist(int[] sortedArr, int num){
if(null == sortedArr || sortedArr.length == 0){
return false;
}
// 左指针
int L = 0;
// 右指针
int R = sortedArr.length - 1;
while (L < R){
// 求 L 和 R 的中间值
// ((R + L)/ 2) == (L + ((R - L) >> 2))
// 因为 R, L 如果都在 Integer.MAX_VALUE 跟前,那么 L + R 容易越界
// >> 1 与 /2 操作相同, 但是 >>1 在计算机的速度更快
int middle = L + ((R - L) >> 1);
if (sortedArr[middle] == num){
return true;
}
if (sortedArr[middle] > num){
R = middle - 1;
continue;
}else {
L = middle + 1;
}
}
return sortedArr[L] == num;
}
/**
* @description: 对数器,用于测验上面方法的实现是否正确。
* 对数器要求思路简单,不需要最优解。
*/
public static boolean comparator(int[] sortedArr, int num){
if (null == sortedArr || sortedArr.length == 0){
return false;
}
boolean b = Arrays.stream(sortedArr).anyMatch(x -> x == num);
return b;
}
public static int[] generateRandomArray(int maxSize, int maxValue){
int size = (int) (Math.random() * (maxSize + 1));
int[] res = new int[size];
for (int i = 0; i<size; i++){
res[i] = (int)(Math.random() * (maxValue + 1)) - (int)(Math.random() * (maxValue + 1));
}
return res;
}
public static void printArray(int[] arr){
if (null == arr){
return;
}
for (int i = 0; i< arr.length; i++){
System.out.printf(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int testTimes = 500;
int maxSize = 100;
int maxValue = 100;
boolean succeed = true;
for (int i=0; i<testTimes; i++){
int[] arr = generateRandomArray(maxSize, maxValue);
int num = (int)(Math.random() * (maxValue + 1)) - (int)(Math.random() * (maxValue + 1));
// 排序,折半查找需要有序数组
Arrays.sort(arr);
if (exist(arr, num) != comparator(arr, num)){
succeed = false;
printArray(arr);
System.out.println(num);
System.out.println(exist(arr, num));
System.out.println(comparator(arr, num));
break;
}
}
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
}
}