STL中與二分查詢相關的4個函式 轉)

2022-03-04 07:13:41 字數 2118 閱讀 4220

二分查詢的原理非常簡單,但寫出的**中很容易含有很多bug,二分查詢一文中講解過如何實現不同型別的二分查詢,但是否一定要自己去實現二分查詢呢?答案顯然是否定的,本文將講解stl中與二分查詢有關函式的具體使用方法及其實現原理。

函式使用

stl中與二分查詢相關的函式有4個,分別是lower_bound, upper_bound, equal_range和binary_search,下面通過乙個簡單的例子說明各個函式的使用方法。

其中每個函式實現的功能如下:

binary_search:查詢某個元素是否出現。

lower_bound:查詢第乙個大於或等於某個元素的位置。

upper_bound:查詢第乙個大於某個元素的位置。

equal_range:查詢某個元素出現的起止位置。注意,終止位置為最後一次出現的位置加一。

其中lower_bound和upper_bound的功能可能比較彆扭,可以這樣看:對於已排序的陣列1 2 2 2 3 4,元素2出現了3次,第一次出現的位置為1,最後一次的位置為3,lower_bound即為這個第一次出現的位置,而upper_bound本意是要標誌最後一次出現的位置,但stl中習慣使用左閉右開的區間,於是upper_bound返回的結果應該為最後一次出現的位置的下乙個位置。當查詢的元素一次都未出現時,二者返回的結果都是第乙個大於該元素的位置。

函式實現

下面我們具體看每個函式的實現細節。我們這裡使用的仍然是sgi 版本的stl,具體版本為v3.3。

lower_bound

lower_bound查詢第乙個大於或等於某個元素val的位置,根據二分查詢,首先找到中間位置的元素mid,然後,

如果mid < val,顯然mid本身及其左邊的元素都不可能是答案了,則把first置為 mid + 1。

如果mid >= val,答案可能是mid本身或者mid左邊的元素,則把last置為mid。

基本思想就是這樣,但stl實現中使用的是迭代器,而迭代器不一定能隨機訪問,於是它需要使用distance函式計算迭代器間的距離,使用advance函式或者自增、自減運算實現迭代器的前進和後退。另外stl實現中沒有在迴圈中使用first和last,而是使用了等價的first和len,這樣可以方便非隨機訪問的迭代器求取中間值。

stl的實現中lower_bound函式本身只是進行了一系列的型別安全性檢查,真正的工作放到了__lower_bound函式中進行。使用額外輔助函式的另乙個目的是在輔助函式中新增模板型別_distance,可以根據模板引數推導機制得到迭代器的距離型別,從而利用這個型別定義變數。

另外,stl的實現有兩個版本,其中乙個使用預設的比較函式<,第二個可以自定義比較方法comp,這裡為了簡潔,只提供了第乙個版本的實現。本質上第二個版本實現中也只是把使用第乙個版本中《進行比較的地方換成呼叫comp方法進行比較,並沒有實質上的區別。以下的每個函式都是如此,不再重複。

下面是具體的實現**。

upper_bound

upper_bound的實現思路跟上面lower_bound類似,只是上面lower_bound是找大於或等於的,這裡是找大於的。得到mid位置的元素後,

如果mid <= val,顯然mid本身及其左邊的元素都不可能是答案了,則把first置為 mid + 1。

如果mid > val,則答案可能是mid本身或者mid左邊的元素,把last置為mid。

下面是**實現。

equal_range

equal_range查詢某個元素出現的起止位置,可以通過以上的lower_bound和upper_bound函式實現。stl中也正是通過這兩個函式實現,不過呼叫之前先進行進行普通二分查詢找到第乙個出現的位置mid後,

在[first, mid)中呼叫lower_bound查詢開始位置。注意,如果該區間沒有找到的話,lower_bound會返回最後的位置mid,而mid此時正是開始位置。

在[mid+1, last)中呼叫lower_bound查詢結束位置,這裡的last即為first + len。

具體的**實現如下。

binary_search

binary_search查詢某個元素是否出現,是最普通的二分查詢。stl的實現中使用了lower_bound查詢第乙個大於或等於該元素的位置,如果該位置的元素同時也是小於或等於目標元素的,則說明該位置的元素確實等於目標元素,查詢成功。否則查詢失敗。

二分搜尋與STL二分查詢

用法 搜尋非遞減數列中是否包含某個元素 當資料量比較大的時候,二分比線性搜尋高效得多。流程 查詢36 實現 物件是非遞減序列,如果當資料無序時,需要預先進行一次排序。int binarysearch int a,int key,int n n為陣列長度 rerurn 0 陣列a中不存在key 複雜度...

STL中的二分查詢

本文 於 使用的時候注意 必須用在非遞減的區間中 二分查詢的原理非常簡單,但寫出的 中很容易含有很多bug,二分查詢一文中講解過如何實現不同型別的二分查詢,但是否一定要自己去實現二分查詢呢?答案顯然是否定的,本文將講解stl中與二分查詢有關函式的具體使用方法及其實現原理。stl中與二分查詢相關的函式...

STL中的二分查詢(binary search)

stl中對於有序序列 vector,list等 提供了相當相當強大的二分搜尋binary search演算法。對於可以隨機訪問容器 如vector等 binary search負載度為對數級別 logn 對於非隨機訪問容器 如list 則演算法複雜度為線性。現在簡要介紹一下幾種常用的binary s...