查詢演算法--二分查詢
阿新 • • 發佈:2019-10-26
1、什麼是二分查詢
二分查詢又稱為折半查詢,首先是從有序陣列(必須是有序陣列)的中間元素開始查詢,如果中間元素是查詢數,就返回;
如果中間元素大於或者小於查詢數,就從大於或小於查詢數的一方繼續執行二分查詢;沒找到就返回空,二分查詢和傳統查詢的差別可以看上圖
2、二分查詢程式碼思路:
- 確定該陣列的中間下標mid
mid=(left+right)/2
- 讓待查詢數target和arr[mid]比較
- 當target>arr[mid]時,說明查詢數在mid右邊,繼續向右邊遞迴查詢
- 當target<arr[mid]時,說明查詢數在mid左邊,繼續向左邊遞迴查詢
- 當target==arr[mid]時,說明查詢數已經找到,返回
- 比較完後找不到,設定遞迴退出條件:left>right
3、程式碼實現:
static List Index=new ArrayList(); //後面查詢元素是多個時使用 public static void main(String[] args) { int arr[]={1,3,5,7,11,11,11,13,17,19,23,29,31,37,41}; Search(arr,0,arr.length-1,11); System.out.println(Index); }
當查詢數是單個時:
public static int Search(int[] arr,int left,int right,int target){ //退出條件,因為最差的就是隻剩下一個數(left==right),當left>right時,說明已經把陣列查詢完了 if (left>right){ return -1; } int mid=(left+right)/2; if (arr[mid]>target){ //查詢數小於arr[mid],左遍歷 return Search(arr,left,mid-1,target); } else if (arr[mid]<target){//查詢數大於arr[mid],右遍歷 return Search(arr,mid+1,right,target); }else {//找到後返回 return mid; } }
當查詢數是多個時:
法一:
if (arr[mid]>target){ //查詢數小於arr[mid],左遍歷 return Search(arr,left,mid-1,target); } else if (arr[mid]<target){//查詢數大於arr[mid],右遍歷 return Search(arr,mid+1,right,target); }else {//找到後返回 Index.add(mid); //先新增找到的這個數 int temp=mid-1; while (true){ //向左迴圈遍歷查詢 if (temp<0 || arr[temp]!=target){ break; } Index.add(temp); temp-=1; } temp=mid+1; while (true){ //向右迴圈遍歷查詢 if (temp>arr.length-1 || arr[temp]!=target){ break; } Index.add(temp); temp+=1; } return mid; }
法一查詢多個用了while迴圈查詢,有人覺得會很繁瑣,其實未必,因為有序陣列的相同元素是挨著的,如 int arr[]={1,3,5,7,11,11,11,13,17,19,23,29,31,37,41};
法二:
else {//找到後返回 Index.add(mid); Search(arr,left,mid-1,target); Search(arr,mid+1,right,target); return mid; }
4、二分查詢的缺陷
- 陣列必須時有序的
- 查詢的必須時陣列
&n