Derek Yen
cyen6
Published in
3 min readAug 26, 2021

--

簡易搜尋法(Sequential Search)& 二元搜尋法(Binary search)

相信大家一定有玩過猜數字的遊戲,或是他更常見出現的名字『終極密碼』

為了避免有人沒玩過,還是簡單介紹一下,這個遊戲就是出題者從 1 -100 之間選擇一個數字,猜題者來猜數字,出題者會依據猜題者給的數字告訴他目前的範圍在哪裡,一直到被某個猜題者猜中為止。

例如:出題者選了一個數字 37

A 玩家:46
出題者:1 到 46
B 玩家:33
出題者:33 到 46
C 玩家: 37
出題者:到了!

所以我們要怎麼猜呢?

可以從頭開始一個一個猜

A 玩家:1
出題者:1 到 100
B 玩家:2
出題者:2 到 100

這其實就是簡易搜尋法!

簡易搜尋法(Sequential Search)- Big O(n)

因為他是一個從頭開始一個一個檢查的搜尋法,所以最差的情況下,執行時間會是 Big O(n),就像如果出題者出 100,你從頭開始猜,就要從 1 猜到 100,是一個滿慢的演算法。

因此要加快找到的速度,除了隨便猜之外,我們很常見的做法是『剖半』。

出題者選: 36
A 玩家:50
出題者:1 到 50
B 玩家:25
出題者:25 到 50
C 玩家:37
出題者:25 到 37
A 玩家:31
出題者:31 到 37
B 玩家:34
出題者:34 到 37
C 玩家:35
出題者:35 到 37
A 玩家:36
出題者:中了

從中間的數字猜,每次都可以排除一半的數字

這就是二元搜尋法

二元搜尋法(Binary search)- Big O(log n)

在這個演算法裡,最差的情況下,執行時間是 Big O(log n),log2 100 = 6.64… 所以最多猜 7 次就一定會猜中,明顯比簡易搜尋法快得多。

在生活中有很多很像二元搜尋法的場景,例如翻字典,當我們想要找一個 I 開頭的字,我們會從中間打開字典,看目前翻到的單字是在 I 的前面還後面,然後繼續重複這個動作,直到找到要的字。

不過二元搜尋法的限制是,搜尋的內容必須先被排序好,像這邊的 1~100 就是有先被排好的。

也因為他是連續性的資料,所以我們在 JavaScript 裡會用到 array,在 Python 裡則會使用 list 來放資料。

範例:給一串排列好的數字 1, 3, 5, 7, 9,猜一個數字看他在第幾個,若找不到這個數字則回傳 None(JavaScript 回傳 null)。

Python 的寫法如下:

JavaScript 的寫法如下:

語法補充

在 Python 裡面基本的加減乘除跟 JavaScript 是一樣的,但平方會寫成 **

>>> 3 ** 2 
9

除法也有分別

當使用 / 時,表示 floating-point division,也就是浮點數的除法
>>> 5 / 2
2.5
當使用 // 時,表示 floor division,會無條件捨去
>>> 5 // 2
2

--

--

Derek Yen
cyen6
Editor for

一個曾經在攝影棚打滾,現在跑來寫程式的三類人,喜歡寫東西,但常常拖延症發作而拖稿,興趣廣泛,舉凡棒球、歷史、人類學,人生目標是走遍世界的每一個角落。 旅遊文章地圖:https://ai86109.github.io/blog/