二分查詢及其變種

2021-09-16 12:45:58 字數 3924 閱讀 2358

3 二分查詢變種總結

時間複雜度概念還不清楚的可以先看****這個文章:

由於二分查詢每次查詢都是從陣列中間切開查詢,所以每次查詢,剩餘的查詢數為上一次的一半,從下表可以清晰的看出查詢次數與剩餘元素數量對應關係

肯定是大於等於1,也就是n(2

k)\frac

(2k)n​

>=1,我們計算時間複雜度是按照最壞的情況進行計算,也就是是查到剩餘最後乙個數才查到我們想要的資料,也就是

n (2

k)\frac

(2k)n​

>=1

=>n=2

kn=2^k

n=2k

=>k=l

og2n

k=log_2^n

k=log2

n​所以二分查詢的時間複雜度為o(l

og2n

)o(log_2^n)

o(log2

n​).

二分查詢是乙個基礎的演算法,也是面試中常考的乙個知識點。二分查詢就是將查詢的鍵和子陣列的中間鍵作比較,如果被查詢的鍵小於中間鍵,就在左子陣列繼續查詢;如果大於中間鍵,就在右子陣列中查詢,否則中間鍵就是要找的元素。

* 二分查詢,找到該值在陣列中的下標,否則為-1

*/static

intbinaryserach

(int

array,

int key)

else

if(array[mid]

< key)

else

}return-1

;}每次移動left和right指標的時候,需要在mid的基礎上+1或者-1, 防止出現死迴圈, 程式也就能夠正確的執行。

注意:**中的判斷條件必須是while (left <= right),否則的話判斷條件不完整,比如:array[3] = ;待查詢的鍵為5,此時在(low < high)條件下就會找不到,因為low和high相等時,指向元素5,但是此時條件不成立,沒有進入while()中。

關於二分查詢,如果條件稍微變換一下,比如:陣列之中的資料可能可以重複,要求返回匹配的資料的最小(或最大)的下標;更近一步, 需要找出陣列中第乙個大於key的元素(也就是最小的大於key的元素的)下標,等等。 這些,雖然只有一點點的變化,實現的時候確實要更加的細心。

二分查詢的變種和二分查詢原理一樣,主要就是變換判斷條件(也就是邊界條件),如果想直接看如何記憶這些變種的竅門,請直接翻到本文最後。下面來看幾種二分查詢變種的**:

查詢第乙個相等的元素,也就是說等於查詢key值的元素有好多個,返回這些元素最左邊的元素下標。

// 查詢第乙個相等的元素

static

intfindfirstequal

(int

array,

int key)

else}if

(left < array.length && array[left]

== key)

return-1

;}

查詢最後乙個相等的元素,也就是說等於查詢key值的元素有好多個,返回這些元素最右邊的元素下標。

// 查詢最後乙個相等的元素

static

intfindlastequal

(int

array,

int key)

else}if

(right >=

0&& array[right]

== key)

return-1

;}

查詢最後乙個等於或者小於key的元素,也就是說等於查詢key值的元素有好多個,返回這些元素最右邊的元素下標;如果沒有等於key值的元素,則返回小於key的最右邊元素下標。

// 查詢最後乙個等於或者小於key的元素

static

intfindlastequalsmaller

(int

array,

int key)

else

}return right;

}

查詢最後乙個小於key的元素,也就是說返回小於key的最右邊元素下標。

// 查詢最後乙個小於key的元素

static

intfindlastsmaller

(int

array,

int key)

else

}return right;

}

查詢第乙個等於或者大於key的元素,也就是說等於查詢key值的元素有好多個,返回這些元素最左邊的元素下標;如果沒有等於key值的元素,則返回大於key的最左邊元素下標。

// 查詢第乙個等於或者大於key的元素

static

intfindfirstequallarger

(int

array,

int key)

else

}return left;

}

查詢第乙個等於key的元素,也就是說返回大於key的最左邊元素下標。

// 查詢第乙個大於key的元素

static

intfindfirstlarger

(int

array,

int key)

else

}return left;

}

// 這裡必須是 <=

while

(left <= right)

else

}return ***;

二分查詢變種較多,不過它們的「套路」是一樣的,以上**就是其套路,如何快速寫出二分查詢的**,只需按照以下步驟即可:

首先判斷出是返回left,還是返回right

因為我們知道最後跳出while (left <= right)迴圈條件是right < left,且right = left - 1。最後right和left一定是卡在"邊界值"的左右兩邊,如果是比較值為key,查詢小於等於(或者是小於)key的元素,則邊界值就是等於key的所有元素的最左邊那個,其實應該返回left。

以陣列為例,如果需要查詢第乙個等於或者小於3的元素下標,我們比較的key值是3,則最後left和right需要滿足以下條件:

我們比較的key值是3,所以此時我們需要返回left。

判斷出比較符號

int mid =

(left + right)/2

;if(array[mid]

? key)

else

也就是這裡的 if (array[mid] ? key) 中的判斷符號,結合步驟1和給出的條件,如果是查詢小於等於key的元素,則知道應該使用判斷符號》=,因為是要返回left,所以如果array[mid]等於或者大於key,就應該使用》=,以下是完整**.

// 查詢小於等於key的元素

int mid =

(left + right)/2

;if(array[mid]

>= key)

else

二分查詢及其變種

返回帶查詢元素key的下標。若沒有key元素,則返回 1。注意 1 while迴圈的條件是low high 2 每次迭代hi mid 1 或lo mid 1 二分查詢,找到該值在陣列中的下標,否則為 1 static int binaryserach int array,int key else i...

二分查詢及其變種

首先說下普通二分查詢的思路 普通二分查詢是在乙個沒有重複的排序陣列中,找到目標值 思路就是先從中間找,如果中間值大於目標值,說明目標值在左半區 如果中間值小於目標值,說明目標值在右邊,當中間值等於目標值,返回他的下標,這裡的陣列預設都不為空 給定乙個有序陣列和乙個關鍵字,找到該值在陣列中的下標,否則...

二分查詢演算法及其變種

前言 二分查詢演算法也稱為折半查詢演算法,是一種在查詢演算法中普遍使用的演算法。其演算法的基本思想是 在有序表中,取中間的記錄作為比較關鍵字,若給定值與中間記錄的關鍵字相等,則查詢成功 若給定的值小於中間記錄的關鍵字,則在中間記錄的左半區間繼續查詢 若給定值大於中間記錄的關鍵字,則在中間記錄的右半區...