package search;
import java.util.ArrayList;
public class BinarySearch {
public static void main(String[] args) {
int[] arr = {1,1,1,1,8,10,89,89,1000,1000,1000,1234};
System.out.println(binarySearch(arr,0,arr.length-1,11));
System.out.println(binarySearch2(arr,0,arr.length-1,1).toString());
}
/**
* 二分查找的时候,数组必须有序,下面的方法只能找到一个等于finVal的下标
* @param arr 数组
* @param left 左边的索引
* @param right 右边的索引
* @param findVal 要查找的值
* @return 如果找到就返回下标,如果找不到就返回-1
*
* 思路:
* 二分查找的数组 前提必须是有序的。
* 1、先求出数组的中间索引mid
* 2、判断arr[mid]于findVal的大小
* 3、如果arr[mid]>findVal ,那么就向左递归去查找
* 4、如果arr[mid]<findVal,那么就向右递归去查找
* 5、当left>right的时候说明数组中没右要查找的值,就返回-1 ,找到的话,就返回索引值
*/
public static int binarySearch(int[] arr,int left,int right,int findVal)
{
if(left > right )
{
return -1;
}
int mid = (left+right)/2;
int midVal = arr[mid];
if(findVal < midVal)
{
return binarySearch(arr,left,mid-1,findVal);
}else if(findVal > midVal)
{
return binarySearch(arr,mid+1,right,findVal);
}else
{
return mid;
}
}
/**
* {1,8,10,89,1000,1000,1000,1234}; 当一个有序数组中有多个相同的值的时候,
* 如果将所有的数组都能找到,比如这里的1000
*
* 思路:
* 1、在找到mid的时候,不要马上返回
* 2、向mid 索引值的左边扫描,将所有等于1000的的下标,加入到集合中ArrayList
* 3、向mid 索引值的右边扫描,将所有等于1000的的下标,加入到集合中ArrayList
* 4、最后将ArrayList返回
*/
public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal)
{
if(left > right )
{
return new ArrayList<Integer>();
}
int mid = (left+right)/2;
int midVal = arr[mid];
if(findVal < midVal)
{
return binarySearch2(arr,left,mid-1,findVal);
}else if(findVal > midVal)
{
return binarySearch2(arr,mid+1,right,findVal);
}else
{
ArrayList<Integer> list = new ArrayList<Integer>();
int temp = mid-1;
//向左扫描
while(true)
{
if(temp < 0 || arr[temp] != findVal)
{
break;
}
//否则就将temp放入到集合中
list.add(temp);
temp--;
}
//将mid放入到集合中
list.add(mid);
//向右扫描
temp = mid+1;
while(true)
{
if(temp > right || arr[temp] != findVal)
{
break;
}
//否则就将temp放入到集合中
list.add(temp);
temp++;
}
return list;
}
}
}