Divide and Conquer
๋ถํ (Divide)
ํด๊ฒฐํ ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ ๊ฐ์ ์์ ๋ถ๋ถ์ผ๋ก ๋๋๋ค.
์ ๋ณต (Conquer)
๋๋ ์์ ๋ฌธ์ ๋ฅผ ๊ฐ๊ฐ ํด๊ฒฐํ๋ค
ํตํฉ (Combine)
(ํ์ํ๋ค๋ฉด) ํด๊ฒฐ๋ ๋ต์ ๋ชจ์๋ค
Top-down Approach (ํํฅ์ ์ ๊ทผ๋ฒ)
: ๋ถํ ์ ๋ณต์ ํํฅ์ ์ ๊ทผ๋ฒ์ด๋ค
๊ฑฐ๋ญ์ ๊ณฑ
๋ฐ๋ณต (Iterative) ์๊ณ ๋ฆฌ์ฆ:
O(n)
C์ ๊ฑฐ๋ญ์ ๊ณฑ = 1์ ๊ฑฐ๋ญ์ ๊ณฑํ ๊ฐ๋งํผ C๋ฅผ ๊ณฑํ๋ ๋ฐฉ์์ผ๋ก ์ฐ์ฐ ์ํ
๋ถํ ์ ๋ณต ๊ธฐ๋ฐ ์๊ณ ๋ฆฌ์ฆ: `O(logn)
๊ฑฐ๋ญ์ ๊ณฑ์ ๋ฐ ์ฉ ๋๋์ด์ ๊ณฑํด ๋๊ฐ๋ ๋ฐฉ๋ฒ์ผ๋ก ํ์ด
์ง์๊ฐ 1์ด ๋๋ฉด ๋ฐ ์๋ฅผ ๊ทธ๋๋ก ๋ฐํ
์๊ฐ ๋ณต์ก๋๋ฅผ
O(log n)
์ผ๋ก ์ค์ผ ์ ์์!
๋ณํฉ ์ ๋ ฌ (Merge Sort)
์ฌ๋ฌ ๊ฐ์ ์ ๋ ฌ๋ ์๋ฃ์ ์งํฉ์ ๋ณํฉํ์ฌ ํ ๊ฐ์ ์ ๋ ฌ๋ ์งํฉ์ผ๋ก ๋ง๋๋ ๋ฐฉ์
๋ถํ ์ ๋ณต ์๊ณ ๋ฆฌ์ฆ ํ์ฉ
์๋ฃ๋ฅผ ์ต์ ๋จ์์ ๋ฌธ์ ๊น์ง ๋๋ ํ์ ์ฐจ๋ก๋ก ์ ๋ ฌํ์ฌ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ์ป์ด๋
top-down ๋ฐฉ์
์๊ฐ ๋ณต์ก๋
O(nlogn)
ex)
def merge(left, right):
result = [] # ๋ ๊ฐ์ ๋ถํ ๋ list๋ฅผ ๋ณํฉํ์ฌ result๋ฅผ ๋ง๋ฆ
while len(left) > 0 and len(right) > 0: # ์์ชฝ list์ ์์๊ฐ ๋จ์์๋ ๊ฒฝ์ฐ
# ๋ sub list์ ์ฒซ ์์๋ค์ ๋น๊ตํ์ฌ ์์ ๊ฒ๋ถํฐ result์ ์ถ๊ฐํจ
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
if len(left) > 0: # ์ผ์ชฝ list์ ์์๊ฐ ๋จ์์๋ ๊ฒฝ์ฐ
result.extend(left)
if len(right) > 0: # ์ค๋ฅธ์ชฝ list์ ์์๊ฐ ๋จ์์๋ ๊ฒฝ์ฐ
result.extend(right)
return result
def merge_sort(m):
if len(m) <= 1: # ๋ฐฐ์ด ํฌ๊ธฐ๊ฐ 0 ์ด๊ฑฐ๋ 1์ธ ๊ฒฝ์ฐ ๋ฐ๋ก return
return m
# 1. Divide ๋ถ๋ถ
mid = len(m) // 2
left = m[:mid]
right = m[mid:]
# list์ ํฌ๊ธฐ๊ฐ 1์ด ๋ ๋๊น์ง merge_sort() ์ฌ๊ท ํธ์ถ
left = merge_sort(left)
right = merge_sort(right)
# 2. Conquer ๋ถ๋ถ : ๋ถํ ๋ ๋ฆฌ์คํธ๋ค ๋ณํจ
return merge(left, right)
ํต ์ ๋ ฌ (Quick Sort)
์ฃผ์ด์ง ๋ฐฐ์ด์ ๋ ๊ฐ๋ก ๋ถํ ํ๊ณ , ๊ฐ๊ฐ์ ์ ๋ ฌํ๋ค
๋ณํฉ ์ ๋ ฌ๊ณผ ๋ค๋ฅธ ์
๋ณํฉ ์ ๋ ฌ์ ๊ทธ๋ฅ ๋ ๋ถ๋ถ์ผ๋ก ๋๋๋ ๋ฐ๋ฉด์, ํต ์ ๋ ฌ์ ๋ถํ ํ ๋, ๊ธฐ์ค ์์ดํ (pivot item) ์ค์ฌ์ผ๋ก, ์ด๋ณด๋ค ์์ ๊ฒ์ ์ผํธ, ํฐ ๊ฒ์ ์ค๋ฅธํธ์ ์์น์ํจ๋ค
๊ฐ ๋ถ๋ถ ์ ๋ ฌ์ด ๋๋ ํ, ๋ณํฉ์ ๋ ฌ์ "๋ณํฉ"์ด๋ ํ์ฒ๋ฆฌ ์์ ์ด ํ์ํ๋, ํต ์ ๋ ฌ์ ํ์๋ก ํ์ง ์๋๋ค.
์๊ฐ ๋ณต์ก๋
nlogn
Hoare-Partition ์๊ณ ๋ฆฌ์ฆ
์์ด๋์ด
P(pivot) ๊ฐ๋ค ๋ณด๋ค ํฐ ๊ฐ์ ์ค๋ฅธ์ชฝ, ์์ ๊ฐ๋ค์ ์ผ์ชฝ ์งํฉ์ ์์นํ๋๋ก ํ๋ค
Pivot์ ๋ ์งํฉ์ ๊ฐ์ด๋ฐ์ ์์น์ํจ๋ค
ํผ๋ด ์ ํ
์ผ์ชฝ ๋ / ์ค๋ฅธ์ชฝ ๋ / ์์์ ์ธ ๊ฐ ๊ฐ ์ค์ ์ค๊ฐ ๊ฐ
ex)
def quick_sort (arr, left, right):
# pivot ์์น ๊ฒฐ์ (pivot์ ๊ธฐ์ค์ผ๋ก ํฐ ๊ฐ์ ์ค๋ฅธ์ชฝ, ์์ ๊ฐ์ ์ผ์ชฝ์ผ๋ก ๊ตฌ๋ถ)
# ์ผ์ชฝ ๋ถ๋ถ์งํฉ ์ ๋ ฌ
# ์ค๋ฅธ์ชฝ ๋ถ๋ถ์งํฉ ์ ๋ ฌ
if left > right:
return
# ํผ๋ด ๊ตฌํ๊ธฐ
pivot = lomuto_partition(arr, left, right)
pivot = hoare_partition(arr, left, right)
# ์ผ์ชฝ ๋ถ๋ถ์งํฉ ์ ๋ ฌ ์คํ
quick_sort(arr, left, pivot-1)
# ์ค๋ฅด์ชฝ ๋ถ๋ถ์งํฉ ์ ๋ ฌ ์คํ
quick_sort(arr,pivot+1, right)
def lomuto_partition(arr, left, right):
# ๋งจ ์ค๋ฅธ์ชฝ ์์๋ฅผ pivot์ผ๋ก ์ค์ ํ๊ณ ,
# i = left -1
# j = left
pivot = arr[right]
i = left -1
for j in range(left, right):
# arr[i] ๊ฐ pivot๋ณด๋ค ์์ผ๋ฉด,
if arr[j] < pivot:
# i๋ฅผ 1 ์ฆ๊ฐ
# arr[j], arr[i] ์์น ๊ตํ
i += 1
arr[i], arr[j] = arr[j], arr[i]
# i๊ฐ ๊ฐ๋ฆฌํค๋ ์์น๊ฐ pivot๋ณด๋ค ์์ ๊ฐ์ ๋ง์ง๋ง ์ธ๋ฑ์ค
# i + 1 ์ ์์น์ pivot์ ๋๊ณ i+1 ๋ฐํ
arr[i+1], arr[right] = arr[right], arr[i+1]
return i+1
def hoare_partition(arr, left, right):
# i, j ์ค์ ํ๊ณ , ํฐ๊ฐ & ์์ ๊ฐ ์ฐพ์์ ์์น ๋ฐ๊ฟ์ฃผ๊ธฐ
i = left
j = right
pivot = arr[left]
# i๊ฐ j๋ณด๋ค ์์ ๋ ๊น์ง ๊ฒ์ํด์ ๋ฐ๋ณต
while i <= j:
# pivot ๋ณด๋ค ํฐ ๊ฐ์ด ๋์ฌ ๋ ๊น์ง i ์ฆ๊ฐ
while i<=j and arr[i] <= pivot:
i += 1
# pivot ๋ณด๋ค ์์ ๊ฐ์ด ๋์ฌ ๋ ๊น์ง j ๊ฐ์
while i <=j and arr[j] >= pivot:
j -= 1
# i๊ฐ j๋ณด๋ค ์์ผ๋ฉด, ์์น ๊ตํ
if i < j:
arr[i], arr[j] = arr[j], arr[i]
arr[left], arr[j] = arr[j], arr[left]
return j # pivot ์์น์ธ j ๋ฐํ
arr = [4,6,3,6,8,0,3,8,10]
quick_sort(arr, 0, len(arr)-1)
print(arr)
์ด์ง ๊ฒ์ (Binary Search)
์๋ฃ์ ๊ฐ์ด๋ฐ์ ์๋ ํญ๋ชฉ์ key ๊ฐ๊ณผ ๋น๊ตํ์ฌ ๋ค์ ๊ฒ์์ ์์น๋ฅผ ๊ฒฐ์ ํ๊ณ ๊ฒ์์ ๊ณ์ ์งํํ๋ ๋ฐฉ๋ฒ
๋ชฉ์ ํค๋ฅผ ์ฐพ์ ๋๊น์ง ์ด์ง ๊ฒ์์ ์ํ์ ์ผ๋ก ๋ฐ๋ณต ์ํํจ์ผ๋ก์จ ๊ฒ์ ๋ฒ์๋ฅผ ๋ฐ์ผ๋ก ์ค์ฌ๊ฐ๋ฉด์ ๋ณด๋ค ๋น ๋ฅด๊ฒ ๊ฒ์์ ์ํํจ
์ด์ง ๊ฒ์์ ํ๊ธฐ ์ํด์๋ ์๋ฃ๊ฐ ์ ๋ ฌ๋ ์ํ์ฌ์ผ ํ๋ค.
๊ฒ์ ๊ณผ์
์๋ฃ์ ์ค์์ ์๋ ์์๋ฅผ ๊ณ ๋ฅธ๋ค
์ค์ ์์์ ๊ฐ๊ณผ ์ฐพ๊ณ ์ ํ๋ ๋ชฉํ ๊ฐ์ ๋น๊ต
๋ชฉํ ๊ฐ์ด ์ค์ ์์์ ๊ฐ๋ณด๋ค
์์ผ๋ฉด ์๋ฃ์ ์ผ์ชฝ ๋ฐ์ ๋ํด์ ์๋ก ๊ฒ์์ ์ํ
ํฌ๋ค๋ฉด ์๋ฃ์ ์ค๋ฅธ์ชฝ ๋ฐ์ ๋ํด์ ์๋ก ๊ฒ์์ ์ํ
์ฐพ๊ณ ์ ํ๋ ๊ฐ์ ์ฐพ์ ๋๊น์ง 1~3 ๋ฐ๋ณต
Last updated
Was this helpful?