Merge Sort
2020-1ํ๊ธฐ, ๋ํ์์ โ์๊ณ ๋ฆฌ์ฆโ ์์ ์ ๋ฃ๊ณ ๊ณต๋ถํ ๋ฐ๋ฅผ ์ ๋ฆฌํ ๊ธ์ ๋๋ค. ์ง์ ์ ์ธ์ ๋ ํ์์ ๋๋ค :)
Merge Sort
<์ ๋ ฌ>์ ์๊ณ ๋ฆฌ์ฆ์ ๊ฐ์ฅ ๊ทผ์์ด ๋๋ ์์ ์ด๋ค. <๋ณํฉ ์ ๋ ฌ; Merge Sort>์ <ํต ์ ๋ ฌ; Quick Sort>๊ณผ ํจ๊ป ์ธ๋ฅ ์ญ์ฌ์์ ์ต๊ณ ์ ์๊ณ ๋ฆฌ์ฆ์ด๋ผ๊ณ ์๊ฐํ๋ค! ๐
Merge Sort๋ <๋ถํ ์ ๋ณต>์ ์ ๋ง ์ถฉ์คํ ์ํํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
โsplit the list into two halves, recursively sort each half, and them merge them.โ
Merge Sort๋ ๊ธฐ๋ฅ์ ์ผ๋ก ๋ดค์ ๋, โMerge Sortโ์ โMergeโ ๋ ๊ฐ์ง ์์ ๋ง ์ํํ๋ฉด ๋๋ค.
function: mergesort($a[1โฆn]$)
if $n > 1$ then
โโ return merge(mergesort($a[1 โฆ n/2]$), mergesort($a[n/2+1 โฆ n]$))
else
โโ return $a$
end if
function: merge($x[1โฆk]$, $y[1โฆl]$)
if $k=0$: โ return $y[1โฆl]$
if $l=0$: โ return $x[1โฆk]$
if $x[1] \le y[1]$ then
โโ return $x[1]$ $\circ$ merge($x[2โฆk]$, $y[1โฆl]$)
else
โโ return $y[1]$ $\circ$ merge($x[1โฆk]$, $y[2โฆl]$)
end if
์ด๋ฒ์๋ Complexity๋ฅผ ๊ณ์ฐํด๋ณด์. ์ ํ์์ ์์ฑํ๋ฉด ์๋์ ๊ฐ๋ค.
\[T(n) = 2 \cdot T(n/2) + O(n)\]๊ณ ์ ๋น์ฉ $O(n)$๋ merge ์์ ์์ ๋ฐ์ํ๋ ๋น์ฉ์ด๋ค!
$a=2$, $b=2$, $c=1$์ด๋ฏ๋ก, $a/b^c = 2/2 = 1$์ด๋ค. ๋ฐ๋ผ์ <Master Theorem>์ ๋ฐ๋ผ
\[O(n) \cdot \log n = O(n \log n)\]์ Complexity๋ฅผ ๊ฐ์ง๋ค!
Merge Sort๋ ๊ฐ๋จํ์ง๋ง ๊ฐ๋ ฅํ๋ค! ๋ณดํต Merge Sort๋ฅผ ์ง์ ๊ตฌํํ๋ ๊ฒฝ์ฐ๋ ๋๋ฌผ์ง๋ง, ์ด๋ค ๊ฒฝ์ฐ์์ Merge Sort์ ์์ด๋์ด๋ฅผ ์ฑ์ฉํด์ ํ์ด์ผ ํ๋ค!
Worst-case Analysis
์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ์ ์ฐจ๋ <ํธ๋ฆฌ Tree>์ ํํ๋ก ํํํ ์ ์๋ค. ์๋ฅผ ๋ค์ด ์๋์ ํธ๋ฆฌ๋ $a_1$, $a_2$, $a_3$ ์ธ ๊ฐ์ ์์์ ๋ํ ์ ๋ ฌ์ ๋์ํํ ๊ทธ๋ฆผ์ด๋ค.
์์ ๊ฐ์ด ์ฃผ์ด์ง ๋ฐฐ์ด์ ๋ํด ์์๋ฅผ ๋น๊ตํ๋ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ๊ฒ ๋๋ฉด, ์ฐ๋ฆฌ๋ ๋ฐฐ์ด์ $n$๊ฐ ์์์ ๋ํ ๊ฐ๋ฅํ ๋ชจ๋ <์์ด Permutation>์ ํ์ธํ๋ ๊ฒ๊ณผ ๋์ผํ๋ค. ์ฆ, $n!$ ๊ฐ์ง์์ ๊ฐ๋ฅํ ์์๋ฅผ ์๊ฐํ๋ค๋ ๋ง์ด๋ค. ์ด๋, โ์ ๋ ฌโ์ด๋ผ๋ ์์ ์ <๋น๊ต ํธ๋ฆฌ; Comparison Tree>์์ ๊ฐ๋ฅํ ํ๋์ <๊ฒฝ๋ก Path>๋ฅผ ์ทจํ๋ ๊ฒ์ด๋ผ๊ณ ํ ์ ์๋ค.
๋น๊ต ํธ๋ฆฌ์์ ๊ฐ์ฅ ๊ธด ๊ฒฝ๋ก(longest path)์ ๊ธธ์ด๋ฅผ ์๊ฐํด๋ณด์. ๋น๊ต ํธ๋ฆฌ๋ ์ด $n!$๊ฐ ๋งํผ์ leaf node๋ฅผ ๊ฐ์ง๋ฏ๋ก ํธ๋ฆฌ์ ๊น์ด(depth)๋ $\log {(n!)}$์ด ๋๋ค. ์ด ํธ๋ฆฌ์ โ๊น์ดโ๋ ๊ณง Worst-case์์์ ๋น๊ต ํ์์ด๋ค!!
์ฝ๊ฐ์ ์ ๋ฆฌ๋ค์ ํ์ฉํ๋ฉด, $\log {(n!)}$์ ๋ํด ์๋๊ฐ ์ฑ๋ฆฝํจ์ ๋ณด์ผ ์ ์๋ค.
\[\log {(n!)} \ge c \cdot n \log n \quad \textrm{for some} \; c > 0\]์ด๊ฒ์ ํจ์ $\log {(n!)}$์ ๋ํด $\Omega \left( n \log {n} \right)$์์ ์๋ฏธํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ค ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ๋ $n$๊ฐ ์์๋ฅผ ์ ๋ ฌํ๋ ๋ฐ์ $\Omega (n \log {n})$ ๋งํผ์ ๋น๊ต๋ ๋ฐ๋์ ์ํํด์ผ ํจ์ ์๋ฏธํ๋ค. ์ฆ, ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด ๊ฐ์ง ์ ์๋ Complexity์ ํํ์ ์ด $n \log {n}$์ด๋ผ๋ ์๋ฏธ์ด๋ค.
๊ทธ๋ฐ๋ฐ ์ฐ๋ฆฌ๋ ์ ๋ฌธ๋จ์์ <Master Theorem>์ผ๋ก Merge Sort๊ฐ $O(n \log {n})$์ Complexity๋ฅผ ๊ฐ์ง๋ค๋ ๊ฑธ ์ ๋ํ๋ค. ์ฆ, Merge Sort์ Complexity๊ฐ $n \log {n}$ ๋ณด๋ค ์ ๋ ๋์์ง์ง ์๋๋ค๋ ๊ฑฐ๋ค! ์ด ๋ง์ ๊ณง $O(n \log {n})$์ ํจ์จ์ ๊ฐ๋ Merge Sort๊ฐ optimal ์ ๋ ฌ ๋ฐฉ์์ด๋ผ๋ ๊ฒ์ ๋งํ๋ค!! $\blacksquare$
p.s. ๋ณธ์ธ๋ ์ฒ์์๋ ์ดํด๊ฐ ์ ๋์ง ์์๋ค. ์๋ง $\Omega (n \log {n})$์ ์๋ฏธ๊ฐ ์ ์๋ฟ์ง ์์๋ ๊ฒ ๊ฐ์๋ฐ, ๋ณธ์ธ์ $\Omega (n \log {n})$๋ฅผ Complextiy์ ํํ์ ์ด๋ผ๊ณ ํด์ํ๋ค. ์ฆ, ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด $\Omega (n \log {n})$์ Complexity๋ฅผ ๊ฐ๋๋ค๋ ๊ฑด ๋ชจ๋ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ $n \log {n}$ ๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ Complexity๋ฅผ ๊ฐ์ง ์ ๋ฐ์ ์๋ค๊ณ ํด์ํ๋ค๋ ๋ง์ด๋ค. ๊ทธ๋ฐ๋ฐ Merge Sort๋ $O(n \log {n})$์ Complextiy๋ฅผ ๊ฐ์ง๋, ์ ๋ $n \log {n}$ ์ด์์ผ๋ก๋ Complexity๊ฐ ์ปค์ง์ง ์๋๋ค. ๊ทธ๋ฌ๋ $O(n \log {n)}$์ $\Omega(n \log {n)}$ ์๋์์ optimal ์ผ ์ ๋ฐ์ ์๋ค!
Merge Sort - Code
์๋ ์ฝ๋๋ ๋ณธ์ธ ์คํ์ผ ๋๋ก ๊ตฌํํ Merge Sort ์ฝ๋๋ค. ์๋๋ ๋ฐฐ์ด์ ์ฌ์ฉํด in_place
๋ก ๊ตฌํํด๋ณด๋ ค๊ณ ํ๋๋ฐ, ๋ญ๊ฐ ์ฝ๋๊ฐ ์์๊ฒ ๋์ค์ง ์์ ๊ฒ ๊ฐ์์ vector
STL๊ณผ in_place๊ฐ ์๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํด๋ดค๋ค.
vector<int> merge(vector<int> left, vector<int> right) {
int left_idx = 0, right_idx = 0;
vector<int> sorted;
while((left_idx < left.size()) && (right_idx < right.size())) {
if (left[left_idx] <= right[right_idx]) {
sorted.push_back(left[left_idx]);
left_idx += 1;
} else {
sorted.push_back(right[right_idx]);
right_idx += 1;
}
}
for (int i = left_idx; i < left.size(); i++) {
sorted.push_back(left[i]);
}
for (int i = right_idx; i < right.size(); i++) {
sorted.push_back(right[i]);
}
return sorted;
}
vector<int> mergeSort(vector<int> arr) {
if (arr.size() <= 1) {
return arr;
}
int mid = arr.size() / 2;
vector<int> leftSide = mergeSort(vector<int>(arr.begin(), arr.begin() + mid));
vector<int> rightSide = mergeSort(vector<int>(arr.begin() + mid, arr.end()));
return merge(leftSide, rightSide);
}
๊ฐ์ธ์ ์ธ ๊ฒฝํ์ผ๋ก MergeSort
๋ python์ผ๋ก ๊ตฌํํ๋๊ฒ ๊ฐ์ฅ ์ฝ๊ณ ํธํ๋ค!