一、二分查找(折半查找)改进的思路:
1.问题提出:在一个有序数组数组{1,8, 10, 89, 1000, 1000,1000,1234} 当中,有多个相同的数值时,如何将所有的数值都查找到,比如这里的 1000,我们利用之前的二分查找只能查找到一个1000的位置,这个时候我们就需要对我们之前写的二分查找进行一个改进了!
2.改进的思路分析:
(1)在我们利用二分查找(折半查找),找到mid值的时候,我们需要马上return;
(2)向mid索引值的左边扫描,将所有满足条件得元素下标,加入到集合ArrayList中
(3)向mid索引值的右边扫描,将所有满足条件得元素下标,加入到集合ArrayList中
(4)最后将ArrayList返回就可以了
二、代码实现:
package com.atguigu.search;
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,1000,1234};
List<Integer> resIndexList=binarySearch(arr,0,arr.length-1,1000);
if (resIndexList.size()==0){
System.out.println("没有找到!");
}else {
System.out.println("找到,位置:"+resIndexList);
}
}
//在有序数组{1,8,10,89,1000,1000,1000,,1234},有多个相同的数值时,如何将所有的数值都查找到,比如这里的1000
//思路分析:
//1.在找到mid值时,不要马上return,
//2.向mid索引值的左边扫描,将所有满足1000,元素的下标,加入到集合ArrayList中
//3.向mid索引值的右边扫描,将所有满足1000,元素的下标,加入到集合ArrayList中
//4.最后将ArrayList返回就可以了
public static List<Integer> binarySearch(int[] arr, int left, int right, int findValue){
//当left>right时,说明递归完毕,但是没有找到
if (left>right){
return new ArrayList<Integer>();
}
int mid=(left+right)/2;
int midVal=arr[mid];
if (findValue>midVal){
return binarySearch2(arr,mid+1,right,findValue);//向右递归
} else if (findValue<arr[mid]){
return binarySearch2(arr,left,mid-1,findValue);//向左递归
}else{
List<Integer> resIndexList=new ArrayList<Integer>();
//向mid索引值的左边扫描,将所有满足1000,元素的下标,加入到集合ArrayList中
int temp=mid-1;
while (true){
if (temp<0||arr[temp]!=findValue){
break;
}
//否则,就将temp放入到集合中
resIndexList.add(temp);
temp--;//temp左移
}
resIndexList.add(mid);
//向mid索引值的右边边扫描,将所有满足1000,元素的下标,加入到集合ArrayList中
temp=mid+1;
while (true){
if (temp>arr.length-1||arr[temp]!=findValue){
break;
}
//否则,就将temp放入到集合中
resIndexList.add(temp);
temp++;//temp右移
}
return resIndexList;
}
}
}