二分查找法 递归与非递归算法 可找寻重复值

二分查找的思路分析
1.首先确定该数组的中间的下标
mid= (left +right)/ 2
2.然后让需要查找的数findVal和arr[mid]比较
2. 1 findVal> arr[mid], 说明你要查找的数在mid的右边,因此需要递归的向右查找
2.2 findVal < arr[mid],说明你要查找的数在mid的左边,因此需要递归的向左查找
2.3 findVal== arr[mid]说明找到,就返回

什么时候我们需要结束递归.
1)找到就结束递归
2)递归完整个数组,仍然没有找到findVal,也需要结束递归当left> right就需要退出
递归算法
增加了找寻所有等于该值的下标



import java.util.ArrayList;
import java.util.List;

public class BinarySearch {

	public static void main(String[] args) {
		int[] a = {1,2,3,4,5,5,9,60};
		System.out.println(binarySearch(a,0,a.length-1,5));

	}
	public static ArrayList<Integer> binarySearch(int[] arr,int left,int right,int finalVal) {
		if(left>right) {
			return new ArrayList<Integer>();
		}
		int mid = (left + right) / 2;
		if(arr[mid]<finalVal) {
			return binarySearch(arr,mid+1,right,finalVal);
		}else if(arr[mid]>finalVal) {
			return binarySearch(arr,left,mid-1,finalVal);
		}else {
			ArrayList<Integer> resIndexList = new ArrayList<Integer>();
			resIndexList.add(mid);
			int temp = mid - 1;
			while(true) {
				if(temp < 0 || arr[temp] != finalVal) {
					//向左扫描
					break;
				}
				resIndexList.add(temp);
				temp--;
			}
			temp = mid + 1;
			while(true) {
				if(temp > arr.length-1 || arr[temp] != finalVal) {
					//向右扫描
					break;
				}
				resIndexList.add(temp);
				temp++;
			}
			return resIndexList;
		}
		
	}
}

非递归
增加了找寻所有等于该值的下标



import java.util.ArrayList;
import java.util.Arrays;

public class BinarySearch {

	public static void main(String[] args) {
		int[] arr = {1,11,11,11,11,67,100};
		System.out.println("1");
		System.out.println(binarySearch(arr,11));

	}
	//	二分查找非递归算法
	//arr升序排列
	public static ArrayList<Integer> binarySearch(int[] arr,int target) {
		ArrayList<Integer> a = new ArrayList<Integer>();
		int left = 0;
		int right = arr.length - 1;
		while(left<right) {
	        // 防止极端情况下(比如两个都是整型的最大值)的整型溢出,使用下面的逻辑求出mid
            int mid = left + (right - left) / 2;
			if (arr[mid] == target) {
				a.add(mid);
				int count = 0;
				while (arr[mid-1] == target) {
					mid--;
					count++;
					a.add(mid);
				}
				mid = mid + count; 
				while (arr[mid+1] == target) {
					mid++;
					a.add(mid);
				}
				break;
			} else if (arr[mid] > target) {
				right = mid - 1;
			} else {
				left = mid + 1;
			}
		}
		return a;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值