狠狠撸

狠狠撸Share a Scribd company logo
關於二分搜尋及三分搜尋
On Binary Search and
Ternary Search
二分搜尋介紹
? 單調數列找給定數字
0 1 2 3 4 5 6
1 3 4 6 8 9 10
1 3 4 6 8 9 10
二分搜尋介紹
? 單調數列找給定數字
0 1 2 3 4 5 6
1 3 4 6 8 9 10
1 3 4 6 8 9 10
二分搜尋介紹
? 單調數列找給定數字
? 單調數列又代表什麼呢?
0 1 2 3 4 5 6
1 3 4 6 8 9 10
1 3 4 6 8 9 10
二分搜尋原理
? 我們先來看這個 6
? 這個 6 隱含了什麼訊息呢?
1 3 4 6 8 9 103 4 6 8 9 10
二分搜尋原理
? 這個 6 告訴我們
? 右邊 比較 大
1 3 4 6 8 9 103 4 6 8 9 10
1 3 4 6 8 9 10
二分搜尋原理
? 相反地
? 左邊 比較 小
3 4 6 8 9 10
二分搜尋原理
? 所以
? 如果想找 4
1 3 4 6 8 9 103 4 6 8 9 10
二分搜尋原理
? 所以
? 如果想找 4
? 4 會在 6 的 左邊
1 3 4 6 8 9 103 4 6 8 9 10
二分搜尋原理
? 繼續搜尋!
? 所以我們現在
? 可以看 左邊 就好
1 3 4 6 8 9 106 8 9 10
二分搜尋原理
? 同樣的方式
? 我們看 3 (我們想找到 4 )
3 6 8 9 101 4
44
二分搜尋原理
? 同樣地
31 6 8 9 10
4
二分搜尋原理
? 同樣地
? 我也會知道 4 在 3 的 右邊
31 6 8 9 10
二分搜尋原理
? 於是我們就找到 4 了!
1 3 4 6 8 9 10
二分搜尋原理
? 於是我們就找到 4 了!
? 不斷 “戳” 點來看的這段過程,就是二分搜尋
1 3 4 6 8 9 10
虛擬碼
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
虛擬碼
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
? 我看不懂虛擬碼 OAO! (以前自學程式的我說)
? 不如我們這樣! (看下頁)
虛擬碼 - 解說
? 我們需要兩個指標:
1 3 4 6 8 9 101 3 4 6 8 9 10
low (低)
low
虛擬碼 - 解說
? 我們需要兩個指標:
high
1 3 4 6 8 9 101 3 4 6 8 9 10
high (低)
low
虛擬碼 - 解說
? 這兩個指標代表
? 目前搜尋的 範圍
low high
1 3 41 3 4 6 8 9 10
low
虛擬碼 -解說
? 有了範圍
high
1 3 4 6 8 9 101 3 4 6 8 9 10
low
虛擬碼 -解說
? 有了範圍
? 接著,我們需要 挑 一個數字來看
high
1 3 4 6 8 9 101 3 4 6 8 9 10
low high
虛擬碼 -解說
? 有了範圍
? 接著,我們需要 挑 一個數字來看
? 我們就挑 中間 這個吧!
mid
mid (中)
1 3 4 6 8 9 103 4 6 8 9 10
high
虛擬碼 - 解說
? 看到這邊是不是覺得很熟悉?
lowlow mid
1 3 4 6 8 9 103 4 6 8 9 10
high
虛擬碼 - 解說
? 看到這邊是不是覺得很熟悉?
? 沒錯! 我們可以只看一邊
1 3 4 6 8 9 106 8 9 10
lowlow mid
虛擬碼 - 解說
? 看到這邊是不是覺得很熟悉?
? 沒錯! 我們可以只看一邊
? 繼續搜尋!
low
3 6 8 9 101 4
low high
虛擬碼 - 解說
? 當搜尋到
? low >= high 或是
? a[mid] = 想找的數字
? 就大功告成了!
1 3 4 6 8 9 10
highlow
虛擬碼 - 整合
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
當 low < high 就繼續搜尋
low high
1 3 4 6 8 9 101 3 4 6 8 9 10
虛擬碼 - 整合
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
1 3 4 6 8 9 103 4 6 8 9 10
low highmid
計算 mid (中點)
虛擬碼 - 整合
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
如果 mid 上的數字就是目標,
傳回結果
low highmid
1 3 4 6 8 9 103 4 6 8 9 10
虛擬碼 - 整合
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
如果目標應該在 右邊
就繼續在 右邊 搜尋
low highmid
1 3 4 6 8 9 103 4 6 8 9 10
虛擬碼 - 整合
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
如果目標應該在 右邊
就繼續在 右邊 搜尋
high
1 3 4 8 9 103 4 6 8 9 10
low
1 3 4 6 8 9 10
虛擬碼 - 整合
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
如果目標應該在 左邊
就繼續在 左邊 搜尋
low highmid
3 6 8 9 101 4
虛擬碼 - 整合
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
如果目標應該在 左邊
就繼續在 左邊 搜尋
low high
3 6 8 9 101 4
虛擬碼 - 整合
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
繼續從新的範圍搜尋
low high
3 6 8 9 101 4
虛擬碼 - 整合
? while (low < high)
mid = (low + high) / 2
if (a[mid] == n)
return mid
else if (a[mid] < n)
low = mid + 1
else if (a[mid] > n)
high = mid – 1
return a[low] == n ? low : -1
? 這樣應該能理解了吧 =D ?
繼續從新的範圍搜尋
low high
Q&A 時間
? 請問下面哪些數列可以做二分搜尋呢?
A) 1, 2, 3, 4, 5, 6, 7
B) 1, 3, 5, 7, 3, 5, 1
C) 4, 3, 2, 9, 8, 12
E) 1, 3, 4, 4, 6, 7, 7
D) 6, 5, 4, 3, 2, 1, -1
F) 2, 2, 2, 2, 2, 2, 2
? 答案: A D E F
Q&A 時間
? 請問下面哪些數列可以做二分搜尋呢?
A) 1, 2, 3, 4, 5, 6, 7
B) 1, 3, 5, 7, 3, 5, 1
C) 4, 3, 2, 9, 8, 12
E) 1, 3, 4, 4, 6, 7, 7
D) 6, 5, 4, 3, 2, 1, -1
F) 2, 2, 2, 2, 2, 2, 2
? 答案: A D E F
你都答對了嗎?
A D E F
Q&A時間 - 接續
數列
整數
實數
可比較
遞增
遞減
單調
Q&A時間 - 接續
數列
整數
實數
可比較
遞增
遞減
單調
只要是一個可以互相 比較 的 單調 數列,即可使用二分搜尋
eg. 1.123, 2, 3.456, 3.456, 5.0, 8, 100, 2016.0325
Q&A時間 - 接續
數列
整數
實數
可比較
遞增
遞減
單調
只要是一個可以互相 比較 的 單調 數列,即可使用二分搜尋
eg. 1.123, 2, 3.456, 3.456, 5.0, 8, 100, 2016.0325
真的只有這樣嗎?
二分搜尋數值範圍
? 二分搜尋不必是數列,也可是一段數值範圍
簡單來說
? 只要圖形畫出來長這樣
? 就可以做二分搜尋了!
想一想 - 1
? 二分搜尋常被說是
? 最容易寫錯 的演算法之一
? 為什麼?
想一想 - 2
? 原問題:找一個數字 = n
想一想 - 2
? 原問題:找一個數字 = n
? 新問題:找第一個 >= n 的數字
? 新問題:找第一個 > n 的數字
? 要怎麼做呢?
三分搜尋
Ternary Search
三分搜尋介紹
? 我們來介紹二分搜尋的姊妹(?)-三分搜尋!
三分搜尋介紹
? 我們來介紹二分搜尋的姊妹(?)-三分搜尋!
? 簡單來說 三分搜尋 就是
找出極值點
三分搜尋原理
? 同樣利用單調性
三分搜尋原理
? 同樣利用單調性
1 個下降坡
三分搜尋原理
? 同樣利用單調性
1 個下降坡 1 個上升坡
三分搜尋原理
? 如果我在圖上任選 2 個點
? 而 左點 比較 高
三分搜尋原理
? 如果我在圖上任選 2 個點
? 而 左點 比較 高
三分搜尋原理
? 如果我在圖上任選 2 個點
? 而 左點 比較 高
三分搜尋原理
? 如果我在圖上任選 2 個點
? 而 左點 比較 高
三分搜尋原理
? 不論怎麼選
三分搜尋原理
? 不論怎麼選
? 極值 都會在 左點 的 右手邊
三分搜尋原理
? 不論怎麼選
? 極值 都會在 左點 的 右手邊
? 因為只有 1 個下降坡,所以 左點 一定會在 下降坡 上
三分搜尋原理
? 同樣地,如果我選 2 個點,右點 比較 高
三分搜尋原理
? 同樣地,如果我選 2 個點,右點 比較 高
三分搜尋原理
? 同樣地,如果我選 2 個點,右點 比較 高
? 極值 都會在 右點 的 左手邊
? 因為只有 1 個上升坡,所以 右點 一定會在 上升坡 上
三分搜尋原理 - 合併
? 統整起來
? 如果我選了 2 個點
三分搜尋原理 - 合併
? 統整起來
? 如果我選了 2 個點
? 1. 左點 比較 高
? 極值 都會在 左點 的 右手邊
三分搜尋原理 - 合併
? 統整起來
? 如果我選了 2 個點
? 1. 左點 比較 高
? 極值 都會在 左點 的 右手邊
? 2. 右點 比較 高
? 極值 都會在 右點 的 左手邊
三分搜尋原理 - 合併
? 統整起來
? 如果我選了 2 個點
? 1. 左點 比較 高
? 極值 都會在 左點 的 右手邊
? 2. 右點 比較 高
? 極值 都會在 右點 的 左手邊
? 所以,雖然比較複雜
我還是可以藉由 選 2 個點
縮小 搜尋範圍
三分搜尋流程
? 左點 比較 高 ? 極值 在 右手邊
三分搜尋流程
? 縮小 搜尋範圍
三分搜尋流程
? 右點 比較 高 ? 極值 在 左手邊
三分搜尋流程
? 可以預見
? 範圍會持續 縮小
? 直到找到 極值
三分搜尋流程
? 可以預見
? 範圍會持續 縮小
? 直到找到 極值
在這裡!
三分搜尋流程
? 可以預見
? 範圍會持續 縮小
? 直到找到 極值
在這裡!
這,就是 三分搜尋
想一想 - 3
? 要怎麼選這 2 個點呢?
想一想 - 3
? 要怎麼選這 2 個點呢?
? 選 1/3 跟 2/3?
想一想 - 3
? 要怎麼選這 2 個點呢?
? 選 1/3 跟 2/3?
? 這樣選真的比較好嗎?
想一想 - 4
? 三分搜尋可不可以
? 一字不改 取代 二分搜尋?
想一想 - 4
? 三分搜尋可不可以
? 一字不改 取代 二分搜尋?
? 為什麼?

More Related Content

Binary Search and Ternary Search