演算法與資料結構 簡單易懂的二分查詢法

2021-09-05 19:49:03 字數 2222 閱讀 9382

查詢問題是計算機中非常重要的基礎問題,但是查詢往往建立在查詢方法上,通常都是排序的資料

對於有序數列,才能使用二分查詢法,所以查詢前就要用到排序演算法。二分查詢法的時間複雜度是o(logn),對於順序陣列,二分查詢法已經是特別快了,所以順序陣列的查詢操作,時間複雜度是o(logn)

在有序陣列中(假設為公升序),先找到中間位置,然後比較要查詢的數是比這個大還是小,比中間小就在左邊找,大就往右邊找

注意,寫**時,要清楚的定義範圍,到底是前閉後閉,還是前閉後開,還是其他。

public static int binarysearch(int arr, int target)  else if(target > arr[mid])  else 

} return -1;

}

上述**就是最早期的二分查詢法,但是還是有bug的,那就是 int mid = (l+r) / 2; 如果l和r都是int中的較大值,那麼相加就會超出int的最大範圍,所以定義中間數時,最好用減法,控制在int範圍以內:

int mid = l + (l-r) / 2;//用減法,整個區間值除以2
,除了迴圈語句,我們還可以使用遞迴的形式實現**:

//使用遞迴實現二分查詢法,思維要容易一些,但是通常遞迴在效能上回略差

//因為每次遞迴會多執行一些判斷條件或者賦值操作

//在arr[l,r]之間查詢target位置,定義好好查詢的範圍區間,是開還是閉,邏輯理清楚了再寫對應**

public static int binarysearch2(int arr, int left, int right , int target)

int mid = left + (right - left) / 2;

if(target == arr[mid])

if(target > arr[mid]) else

}

上面假設二分查詢的資料是沒有重複的,假設資料有重複的值,如果按照上述方法查詢,則最後找到位置是不穩定的,有可能是這一串重複數字的第乙個或者最後乙個或者中間的值。此時,就需要定義floor和ceil兩個方法。

floor: 很常見的乙個方法,通常是去比目標值小的最大值,或者向下取整

ceil: 與floor相反,是查詢比目標值大的最小值,或者向上取整。

這裡,我們定義的floor和ceil函式分別是目標值的最小位置和最大位置,如果資料中沒有目標值,則是比目標值小的最大值的位置,以及比目標值大的最小值的位置。實現如下:

floor函式

public static int floor(int arr, int left, int right , int target) 

//遞迴實現

//查詢目標值的最小位置,如果目標值不存在,則返回小於目標值的最大數的位置, floor為當前找到的最合適的位置,初始傳入為-1

private static int floor(int arr, int left, int right , int target, int floor)

int mid = left + (right - left) / 2;

if(arr[mid] == target)

if(target < arr[mid]) else

}

ceil函式:

public static int ceil(int arr, int left, int right , int target) 

//遞迴實現

//查詢目標值的最大位置,如果目標值不存在,則返回大於目標值的最小位置

public static int ceil(int arr, int left, int right , int target, int ceil)

int mid = left + (right - left) / 2;

if(target == arr[mid])

if(target < arr[mid]) else

}

後面將在二分查詢法的基礎上去介紹二叉樹和紅黑樹兩種資料結構。

資料結構與演算法 二分查詢

二分查詢的思想是在已經排序 公升序 的陣列中,如果要查詢的數比中位數小,那麼其位置只可能在左半部分,相反只能在右半部分。這樣每次把查詢區間縮小一半,比順序查詢效率快得多。非遞迴寫法 public static int binarysearchinasclooply int nums,int star...

資料結構與演算法,二分查詢

1.時間複雜度 每次能去掉一半即 logn 2.實現方式 while迴圈 與 遞迴 我更推薦 while 迴圈,因為遞迴有個潛在的問題就是 stack over flow 堆疊溢位 而且在實際工程中是盡量避免遞迴的。雖然遞迴寫起來方便,也不容易出錯。3.實現關鍵點 我總結了下,一共有以下四點 sta...

資料結構與演算法 二分查詢

基礎概念 二分查詢又稱折半查詢,它是一種效率較高的查詢方法。二分查詢要求 線性表是有序表,即表中結點按關鍵字有序,並且要用陣列作為表的儲存結構。不妨設有序表是遞增有序的。通俗理解 每次首先找到陣列的中間位置 middle 然後把待查詢數 target 與middle進行比較。如果查詢數target ...