1、二分法查找元素的方式又叫做折半查找,从数组中查找,而且数组是已经按照升序或者降序排列好的,如果数组的元素是无序的则不能使用二分法查找。
比如说我们有一个数组,这个数组有100万个元素,此时我们有一个需求:得到了一个数据,要判断这个数组中是否有这个数据,如果有则返回对应的下标索引,如果没有就返回-1。
二分查找算法要实现这个需求有两种方案可选,一种就是循环查找,一种就是递归法查找。
2、二分查找要求:
(1)必须采用顺序存储结构
(2).必须按关键字大小有序排列。
3、二分查找优缺点:
优点是比较次数少,查找速度快,平均性能好;
其缺点是要求待查表为有序表,且插入删除困难。
因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
一、循环方法实现二分查找
/**
* 二分查找,返回该值第一次出现的位置(下标从 0 开始)
* @param nums 查询数组
* @param start 开始下标
* @param end 结束下标
* @param findValue 要查找的值
*/
public class BinarySearch { public static void main(String[] args) { int[] nums = {1, 2, 6, 15, 18, 20, 25, 27, 35, 40, 45, 56, 62, 78, 88}; int findValue = 35; int binaryResult = binarySearch(nums, 0, nums.length - 1, findValue); System.out.println("元素第一次出现的位置(从0开始):" + binaryResult); } public static int binarySearch(int[] nums, int start, int end, int findValue) { while (start <= end) { int middle = (start + end) / 2; if (findValue == nums[middle]) { //查找值等于中间值直接返回 return middle; } else if (findValue < nums[middle]) { //小于中间值,在中间值之前的数据中查找 end = middle - 1; } else { //大于中间值,在中间值之后的数据中查找 start = middle + 1; } } return -1; } }
执行结果如下:
二、递归实现二分查找
/**
* 二分查找,返回该值第一次出现的位置(下标从 0 开始)
* @param nums 查询数组
* @param start 开始下标
* @param end 结束下标
* @param findValue 要查找的值
*/
public class BinarySearch { public static void main(String[] args) { int[] nums = {1,2,6,15,18,20,25,27,35,40,45,56,62,78,88}; int findValue = 25; int binaryResult = binarySearch(nums,0,nums.length-1,findValue ); System.out.println("元素第一次出现的位置(从0开始):" + binaryResult); } private static int binarySearch(int[] nums, int start, int end, int findValue) { if(start <= end){ int middle = (start + end) / 2; int middleValue = nums[middle];//中间值 if (findValue == middleValue){ //查找值等于中间值直接返回 return middle; }else if (findValue < middleValue){ //小于中间值,在中间值之前的数据中查找 return binarySearch(nums,start,middle-1, findValue); }else{ //大于中间值,在中间值之后的数据中查找 return binarySearch(nums,middle+1,end, findValue); } } return -1; } }
执行结果如下: