二分查找算法(java实现)

二分查找算法(java实现)

二分查找 又叫折半查找,是一种简单又快速的查找算法 适用于(有序列表)

​ 每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为0。二分查找是一种非常非常高效的查询算法,时间复杂度为O(logn)。


算法前提:

  • 必须采用顺序存储结构
  • 必须按关键字大小有序排列

例如:

请对一个有序数组 arr 进行 二分查找 {1,8, 10, 89, 1000, 1000, 1234} ,输入一个数看看该数组是否存在此数,并且求出下标,如果没有就提示"没有这个数",有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000.

思路分析:(递归实现)

  1. 确定数组arr的中间的下标:

​ mid = (left + right) / 2 | left为数组最左边下标为 0,right为数组最右边下标 为arr.length - 1

  1. 将待查找的数 findVal 与 数组中间的值 arr[mid]比较:

​ 当 findVal > arr[mid] 时,说明 待查找的数 findVal 在 arr[mid] 的 右边 ,需要 递归向右 继续查找。

​ 当 findVal < arr[mid] 时,说明 待查找的数 findVal 在 arr[mid] 的 左边 ,需要 递归向左 继续查找。

​ 当 findVal = arr[mid] 时,说明 待查找的数 findVal 为 arr[mid] 返回改值下标

  1. 递归结束条件:

    找到值 结束递归

    递归查找完整个数组,还未找到 待查找的数 findVal ,也结束递归 (当 left > right 时)


    代码实现:

    import java.util.ArrayList;
    import java.util.List;
    
    public class BinarySearch {
    
    	public static void main(String[] args) {
    		int arr[] = { 1, 8, 10, 89,1000,1000, 1234 };
    	
    		List<Integer> resIndexList = binarySearch(arr, 0, arr.length - 1, 1000);
            
    		System.out.println("resIndexList=" + resIndexList);
    		
    	}
    
    	// 二分查找算法
    		/**
    		 * 
    		 * @param arr
    		 *            数组
    		 * @param left
    		 *            左边的索引
    		 * @param right
    		 *            右边的索引
    		 * @param findVal
    		 *            要查找的值
    		 * @return 如果找到就返回下标,如果没有找到,就返回 -1
    		 */
    	public static List<Integer> binarySearch(int[] arr, int left, int right, int findVal) {
    		    // 当 left > right 时,说明递归整个数组,但是没有找到
    				if (left > right) {
    					return new ArrayList<Integer>();
    				}
    				
    				int mid = (left + right) / 2;
    				int midVal = arr[mid];
    
    				if (findVal > midVal) { // 向 右递归
    					return binarySearch(arr, mid + 1, right, findVal);
    				} else if (findVal < midVal) { // 向左递归
    					return binarySearch(arr, left, mid - 1, findVal);
    				} else {
    					List<Integer> resIndexList = new ArrayList<>();
    					int temp = mid-1;
    					
    					while(true) {
    						if (temp < 0|| arr[temp] != findVal) {
    							break;
    						}
    						resIndexList.add(temp);
    						temp -= 1;
    					}
    					resIndexList.add(mid);
    					
    					temp = mid+1;
    					while(true) {
    						if (temp > arr.length -1|| arr[temp] != findVal) {
    							break;
    						}
    						resIndexList.add(temp);
    						temp += 1;
    					}
    					
    					return resIndexList;
    				}
    	}
    //public static int binarySearch(int[] arr, int left, int right, int findVal) {
    //		
    //
    //		// 当 left > right 时,说明递归整个数组,但是没有找到
    //		if (left > right) {
    //			return -1;
    //		}
    //		int mid = (left + right) / 2;
    //		int midVal = arr[mid];
    //
    //		if (findVal > midVal) { // 向 右递归
    //			return binarySearch(arr, mid + 1, right, findVal);
    //		} else if (findVal < midVal) { // 向左递归
    //			return binarySearch(arr, left, mid - 1, findVal);
    //		} else {
    //			
    //			return mid;
    //		}
    //
    //	}
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值