使用前提:数组已经按升序排列
基本原理:首先将要找的元素key与数组的中间元素比较
1、如果key小于中间元素,只需要在数组的前一半元素中继续查找
2、如果key和中间元素相等,匹配成功,查找结束
3、如果key大于中间元素,只需要在数组的后一半元素中继续查找
low mid high
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]
int[] array 2 5 8 10 15 25 35 45 55 65 75 85 95
假设查个5:首先定义好一个最小值和一个最大值,我们在搞一个中间值,
第一轮5和35比较,5比35小,所以满足基本原理的1,把high的值移到中间值的前面
即[5],mid = (low + high) / 2 =( 0 + 5) / 2 = 2,所以mid的值移到[2]
第二轮5和8比较,5比8小,同理,把high的值移到中间值的前面,(high = mid - 1)
即[1], mid = (0 + 1) / 2 = 0,所以mid的值移到[0]
第三轮5和2比较,5比2大,满足基本原理3,把low的值移到中间值的后面,(low = mid + 1)
即[1],mid = (1 + 1)/ 2 = 1,所以把mid的值移到[1],三个共线了很特殊
第四轮,5和5比较,满足基本原理2,匹配成功,查找结束
import java.util.Arrays;
import java.util.Scanner;
/**
*
* 二分查找法:前提-数组已经按照升序排列
* @author Monster丶ZF
* @version1.8
* @data 2019年4月14日
* @remakeTODO
*/
public class BinarySearchDemo {
public static void main(String[] args) {
// 基本原理:首先将要找的元素key与数组的中间元素比较
// 1、如果key小于中间元素,只需要在数组的前一半元素中继续查找
// 2、如果key和中间元素相等,匹配成功,查找结束
// 3、如果key大于中间元素,只需要在数组的后一半元素中继续查找
final int N = 10;
Scanner input = new Scanner(System.in);
int[] array = new int[N];
for (int i = 0; i < array.length; i++) {
array[i] = (int)(Math.random()*10000) % 201;
}
System.out.println("排序前:");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + "\t"); //随机生成0-200的数组元素
}
System.out.println();
Arrays.sort(array); //调用类库的快速排序默认从小到大排序
System.out.println("排序后:");
for (int i = 0; i < array.length; i++) { //输出排序好的数组元素
System.out.print(array[i] + "\t");
}
System.out.println();
System.out.println("请输入要查找的数字:");
int searchNum = input.nextInt();
int searchIndex = -1;
long start1Time = System.currentTimeMillis();
for (int i = 0; i < array.length; i++) {
if(searchNum == array[i]){
// System.out.println("找到了!");
searchIndex = i;
break;
}
}
if(searchIndex == -1){
System.out.println("很遗憾,没有找到您输入的数字");
}else{
System.out.println("找到了!下标为:" + searchIndex);
}
long end1Time = System.currentTimeMillis();
System.out.println("普通查找用时"+(end1Time - start1Time) + "毫秒");
boolean isFind = false; //是否找到
int low = 0; //下届下标
int high = array.length - 1; //上届下标
// 不知道要查找多少次! for循环就不好
long start2Time = System.currentTimeMillis();
while(high >= low){
//计算中点下标
int mid =(high + low) / 2;
//1、如果key小于中间元素,只需要在数组的前一半元素中继续查找
if(searchNum < array[mid]){
high = mid - 1;
}else if(searchNum > array[mid]){ //3、如果key大于中间元素,只需要在数组的后一半元素中继续查找
low = mid + 1;
}else{ //2、如果key和中间元素相等,匹配成功,查找结束
System.out.println("找到了数字!下标为:" + mid);
isFind = true;
break;
}
}
if(!isFind){ // 等价于isFind = 0
System.out.println("没有找到您输入的数字!");
}
long end2Time = System.currentTimeMillis();
input.close();
System.out.println("二分查找用时"+(end2Time - start2Time) + "毫秒");
}
}
大家也可以自己把N调大些,然后随机数的范围也调大些自行测试一下两个查找的快慢