Java 手寫二分查找算法,遞歸與非遞歸
二分查找也稱折半查找(Binary Search),它是一種效率較高的查找方法。但是,折半查找要求線性表必須採用順序存儲結構,而且表中元素按關鍵字有序排列。
你要走二分查找,你首先得支楞起來啊~(數組有序)
一.遞歸實現
註解基本都有,這裏不再詳細解釋了,我們這個二分查找需要找出所有的元素下標~
package DataStructure.BinarySearch;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BinarySearchDemoDigui {
public static void main(String[] args) {
int arr[]={1,2,3,3,3,4,5,5,6,6,7};
Arrays.sort(arr);//二分查找要保證數組有序,其實沒必要有這一步~~
System.out.println(get(arr,0,arr.length-1,300));
}
public static List get(int arr[],int left,int right,int value){
int mid=(left+right)/2;
int midval=arr[mid];
if(left>right) return new ArrayList(); //結束條件 那左下標都大於右下標了肯定返回了~
if(value>midval){ //如果我們要找得值是大於中間值的,那它肯定是在中間值右邊的,那我們就只用考慮中間值右半部分的
return get(arr,mid+1,right,value);
}else if(value<midval){ //如果我們要找得值是小於中間值的,那它肯定是在中間值左邊的,那我們就只用考慮中間值左半部分的
return get(arr,left,mid-1,value);
}else {
List<Integer> list=new ArrayList(); //這裏我們優化一下算法,這裏返回所有與查找值相同的數組下標,用list收集起來
int temp=mid-1; //首先在這個條件裏的值肯定是等於要查找數的值,那首先數組是有序的,那我們只需要從左或者從右判斷是否有與相同值即可
while(true){
if(temp<0||arr[temp]!=value){ //結束條件,下同
break;
}
list.add(temp); //符合條件就加到list裏
temp-=1; // 繼續向左查找
}
list.add(mid); //別忘了把中間值加進去
temp=mid+1; //繼續向右查找
while(true){
if(temp>arr.length-1||arr[temp]!=value){
break;
}
list.add(temp);
temp+=1;
}
return list;
}
}
}
二. 非遞歸實現
package DataStructure.BinarySearch;
import java.util.ArrayList;
import java.util.List;
/**
* 二分查找非遞歸
*/
public class BinarySearchDemo {
public static void main(String[] args) {
int arr[]={1,2,3,4,5,6,7,7,7};
System.out.println(getIndex(arr, 7));
}
public static List<Integer> getIndex(int[] arr,int val){
int left=0;
int right=arr.length-1;
List<Integer> list=new ArrayList<>();
while(left<=right){ //結束條件肯定是left>right
int mid=(left+right)/2; //那我們肯定每次都需要計算mid值啊
if(val==arr[mid]){ //這裏我判斷了如果查到了,那接下來一系列操作與遞歸寫的相同(就是向左向右查找相同值加到list中)
int temp=mid-1;
while(true){
if(temp<0||arr[temp]!=val) {
break;
}
list.add(temp);
temp-=1;
}
list.add(mid);
temp=mid+1;
while(true){
if(temp>arr.length-1||arr[temp]!=val) {
break;
}
list.add(temp);
temp+=1;
}
return list;
}else if(val<arr[mid]){
right=mid-1;
}else {
left=mid+1;
}
}
return new ArrayList<>();
}
}