寫好正確的二分搜尋

2021-05-27 23:09:24 字數 2206 閱讀 5373

今天再次解決乙個需要使用二分查詢的問題,再一次的,我又沒有一次過寫對.(為什麼我說"又"?)

抓狂了,似乎開始有一些"二分查詢恐懼症".

為了以後能夠一次將這個基本的演算法寫對,我決定再仔細研究一下.我之前有寫過乙個二分查詢的演算法,在

這裡,這一次再以這個問題為例來說明.

我今早寫下的錯誤**類似於下面的樣子:

#include 

<

stdio.h

>

intsearch(

intarray, 

intn, 

intv)

else

if(array[middle] 

<

v)else

}return-1

;}intmain()

;intm =

search(array, 

sizeof

(array)

/sizeof

(array[

0]), 1);

printf(

"m = %d\n

", m);

return0;

} 實際上,如果使用測試用例來測試,這個演算法並不是在所有情況下都會出錯的,還是有時可以得到正確的結果的.但是,你能看出來它錯在哪兒嗎?

在這裡,迴圈的開始處,把迴圈遍歷的序列區間是這樣的:

left =0

, right =n;

while

(left 

<

right)

也就是說,這是乙個左閉右開的區間:[0, n).

但是,在迴圈內部, 卻不是這樣操作的:

middle 

=(left 

+right) /2

;if(array[middle] 

>

v)else

if(array[middle] 

<

v)else

當array[middle] > v條件滿足時, 此時v如果存在的話必然在左閉右開區間[left, middle)中, 因此,當這個條件滿足時, right應該為middle, 而在這裡, right賦值為middle - 1了, 那麼, 就有可能遺漏array[middle - 1] = v的情況.

因此,這種錯誤的寫法並不是在所有的情況下都會出錯,有時還是可以找到正確的結果的.

這是一種典型的二分查詢演算法寫錯的情況,迴圈體是左閉右開區間,而迴圈體內部卻是採用左閉右閉區間的演算法進行操作.

下面給出的兩種正確的演算法,演算法search是左閉右閉區間演算法,而演算法search2是左閉右開區間演算法,可以對比一下差異.

intsearch(

intarray, 

intn, 

intv)

else

if(array[middle] 

<

v)else

}return-1

;}intsearch2(

intarray, 

intn, 

intv)

else

if(array[middle] 

<

v)else

}return-1

;}

下面再給出另一種典型的錯誤的二分查詢演算法,當查詢的元素不在序列內時,它可能造成程式的死迴圈.

intsearch(

intarray, 

intn, 

intv)

else

if(array[middle] 

<

v)else

}return-1

;}為什麼會造成死迴圈?

從迴圈條件來看,這個演算法的操作區間是左閉右閉區間的,因此當array[middle] > v時,v如果存在的話應該在[left, middle- 1]中,因此此時right應該是middle - 1,而不是middle;類似的,當array[middle] < v時,下一次操作的區間應該是[middle + 1, right]中.而當元素不存在這個序列中時,演算法在乙個錯誤的區間中迴圈,但是又不能終止迴圈,於是就造成了死迴圈.

因此,要將二分查詢演算法寫對,其實很多人都大概知道思想,具體到編碼的時候,就會被這些看似微小的地方搞糊塗.因此,需要注意這一點:

演算法所操作的區間,是左閉右開區間,還是左閉右閉區間,這個區間,需要在迴圈初始化,迴圈體是否終止的判斷中,以及每次修改left,right區間值這三個地方保持一致,否則就可能出錯.

如何寫好乙個二分搜尋

最近寫了乙個二分搜尋,結果不盡人意,總是出錯。所以翻了一些部落格,看到一些關於使用迴圈不變體的方法來寫二分搜尋。如何寫出正確的二分搜尋 我就寫好乙個二分搜尋進行了一下總結 確定你這個二分的目的,以下會舉7個例子說一下常用的求解target 確定條件,就三個,s mid 確定迴圈的條件 while l...

Java 二分搜尋 二分查詢

對陣列元素進行逐個查詢顯然是費時費力的工作,我們可以使用一些方法快速地搜尋出陣列中元素的指定位置.接下來我們介紹一種方法 二分搜尋法 二分搜尋法充分利用了元素間的次序關係.基本思想 將n元素分成個數大致相同的涼拌,取arr n 2 與欲查詢的x做比較,如果 下面將採用兩種方式 遞迴 非遞迴 來展示二...

二分(二分答案 二分搜尋)與單調性

經典二分搜尋是二分空間範圍。二分答案又叫二分猜值,是二分解的值空間。其實可以統一,普通的二分搜尋也是二分答案值域 下標空間,也是猜值。二分必須滿足單調性,最直觀的,二分搜尋只能在有序陣列上進行。單調性體現在,下標和元素值是單調的,也就是 if j i 有 a j a i 一般二分答案解決的問題是最優...