๐ ํฌ์คํธ 3: ๊ฒ์์ ์ฑ๋ฐฐ: O(log N)
Source: Dev.to
O(logโฏN)์ด ์ ํ ํ์๋ณด๋ค ๋น ๋ฅธ ์ด์
์ด์ ๊ธ์์๋ O(Nยฒ) ์์ O(N) ๋ก ์ด๋ป๊ฒ ์ ํํ ์ ์๋์ง ์ดํด๋ณด์์ต๋๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๋ ๋ ๋น ๋ฅด๊ฒ ๊ฐ ์ ์์ต๋๋ค. O(logโฏN) (๋ก๊ทธ) ๋ณต์ก๋๋ ์ ๋ ฅ ํฌ๊ธฐ์ ๊ฑฐ์ ์ํฅ์ ๋ฐ์ง ์๋ ์ฑ์ฅ๋ฅ ๋๋ฌธ์ ๋ชจ๋ ํ์ ์๊ณ ๋ฆฌ์ฆ์ ๊ธ๋ณธ์ ๊ธฐ์ค์ ๋๋ค.
| ์ ๋ ฅ ํฌ๊ธฐ (N) | O(N) ๋จ๊ณ | O(logโฏN) ๋จ๊ณ |
|---|---|---|
| 1โฏ000 | 1โฏ000 | 10 |
| 1โฏ000โฏ000 | 1โฏ000โฏ000 | 20 |
| 1โฏ000โฏ000โฏ000 | 1โฏ000โฏ000โฏ000 | ~30 |
์ด ์๋๋ฅผ ๊ตฌํํ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ด์ง ํ์์ ๋๋ค. ๊ฐ ๋จ๊ณ๋ง๋ค ๋จ์ ํ์ ๊ณต๊ฐ์ ์ ๋ฐ์ ๋ฒ๋ฆฝ๋๋ค.
์ด์ง ํ์ ๊ฐ์
์ด์ง ํ์์ ์ ๋ ฌ๋ ์๋ฃ ๊ตฌ์กฐ์์๋ง ๋์ํฉ๋๋ค. ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ์ค๊ฐ ์์(
mid)๋ฅผ ํ์ธํฉ๋๋ค. - ์ค๊ฐ ๊ฐ์ด ๋ชฉํ๋ณด๋ค ์์ผ๋ฉด ์ผ์ชฝ ์ ๋ฐ์ ๋ฒ๋ฆฝ๋๋ค.
- ์ค๊ฐ ๊ฐ์ด ๋ชฉํ๋ณด๋ค ํฌ๋ฉด ์ค๋ฅธ์ชฝ ์ ๋ฐ์ ๋ฒ๋ฆฝ๋๋ค.
- ๋งค ๋ฐ๋ณต๋ง๋ค ๋ฌธ์ ๋ฅผ ์ ๋ฐ์ผ๋ก ์ค์ด๋ฉฐ(
logโ) ์ฌ๊ท์ ์ผ๋ก ๋ฐ๋ณตํฉ๋๋ค.
Elixir์์์ ํจ์
Elixir์ ๊ธฐ๋ณธ ์ฐ๊ฒฐ ๋ฆฌ์คํธ๋ ๋จธ๋ฆฌ๋ง ์๊ณ ์์ต๋๋ค. ์ธ๋ฑ์ค N/2์ ์๋ ์์์ ์ ๊ทผํ๋ ค๋ฉด ๋ฐํ์์ด N/2๊ฐ์ ์์๋ฅผ ์ํํด์ผ ํ๋ฏ๋ก O(N) ์ด ๋ฉ๋๋ค. ๊ฐ ์ด์ง ํ์ ๋จ๊ณ๊ฐ ์ค๊ฐ์ ์ฐพ๋ ๋ฐ O(N) ๋น์ฉ์ด ๋ ๋ค๋ฉด ์ ์ฒด ๋ณต์ก๋๋ O(NโฏlogโฏN) ๊ฐ ๋์ด ์ด์ ์ด ์ฌ๋ผ์ง๋๋ค.
Erlang/Elixir ์ํ๊ณ์์ ์ง์ ํ O(logโฏN) ๋ฅผ ์ป์ผ๋ ค๋ฉด O(1) ์ธ๋ฑ์ค ์ ๊ทผ์ด ๊ฐ๋ฅํ ์๋ฃ ๊ตฌ์กฐ๊ฐ ํ์ํฉ๋๋ค. ํํ์ด ๋ฐ๋ก ๊ทธ ์ญํ ์ ํฉ๋๋ค.
Elixir ๊ตฌํ
defmodule BinarySearch do
@doc """Starts a binary search with O(log N) complexity."""
def search(list, target) do
# Convert the list to a tuple for O(1) index access
array = List.to_tuple(list)
# Kick off the recursion: low = 0, high = size - 1
binary_search_recursive(array, target, 0, tuple_size(array) - 1)
end
# Failure condition โ low has crossed high, target not found
defp binary_search_recursive(_array, _target, low, high) when low > high do
:not_found
end
# Main recursive step
defp binary_search_recursive(array, target, low, high) do
# 1. Compute the middle index
mid = div(low + high, 2)
# 2. Retrieve the middle value (O(1) in a tuple)
# Tuples in Erlang are 1โbased, so add 1
current_value = :erlang.element(mid + 1, array)
# 3. Success condition
if current_value == target do
mid
# 4. Target is greater โ discard left half
else
if current_value < target do
binary_search_recursive(array, target, mid + 1, high)
# 5. Target is smaller โ discard right half
else
binary_search_recursive(array, target, low, mid - 1)
end
end
end
end
์ด ํจ์๋ ๊ฐ ์ฌ๊ท ํธ์ถ์ด ํ์ ๊ณต๊ฐ์ ์ ๋ฐ์ผ๋ก ์ค์ด๋ฉด์ ์ค๊ฐ ์์์ ์์ ์๊ฐ์ผ๋ก ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ ์ง์ ํ O(logโฏN) ๋์์ ๋ณด์ฌ์ค๋๋ค.
๋ค์ ์ฃผ์ ๋?
O(logโฏN) ๊ฐ ํ์์ ์ต์ ์ ๋ณต์ก๋๋ผ๋ฉด, ์ ๋ ฌ์ ๋ํ ์ต์ ์ ๋ณต์ก๋๋ ๋ฌด์์ผ๊น์? ๋ค์ ๊ธ์์๋ O(NโฏlogโฏN) (์ ํ ๋ก๊ทธ) ์๊ณ ๋ฆฌ์ฆ์ ์ดํด๋ณผ ์์ ์ด๋ฉฐ, ๋ณํฉ ์ ๋ ฌ์ ์ด์ ์ ๋ง์ถฐ ๋ก๊ทธ ๊ธฐ๋ฐ ๋ถํ โ์ ๋ณต ์ ๋ต๊ณผ ์ ํ ๋ณํฉ ์์ ์ ๊ฒฐํฉํ๋ ๋ฐฉ์์ ๋ค๋ฃฐ ๊ฒ์ ๋๋ค.