ํต ์ ๋ ฌ
๊ฐ๋
ํต ์ ๋ ฌ์ ์ธ๋ถ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
pivot์ด๋ผ๋ ์์๋ฅผ ์ ํํ ํ, pivot์ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ์๋ pivot๋ณด๋ค ์์ ์์๋ค์ ๋๊ณ ์ค๋ฅธ์ชฝ์๋ pivot๋ณด๋ค ํฐ ์์๋ค์ ๋๋๋ค.
์ดํ ์ํํธ์ถ์ ์ด์ฉํ์ฌ ์ฌ๊ท์ ์ผ๋ก ์ผ์ชฝ, ์ค๋ฅธ์ชฝ์ผ๋ก ๋ถ๋ฅํด๋ ์์๋ค์ ๋ํด ์ ๊ณผ ๊ฐ์ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค. ์์ ๊ทธ๋ฆผ์ ์ค๋ฅธ์ชฝ ์์๋ค์ ๋ํด ์ํํธ์ถํ ๋ชจ์ต์ด๋ค.
๋ถํ ์ด ๋ถ๊ฐ๋ฅํ ๋๊น์ง ๋ฐ๋ณตํ๋ค๋ณด๋ฉด ์ต์ํ์ ์์๋ก ๋๋์ด์ง๊ณ ์ดํ ์์๋๋ก ๊ฒฐํฉ์ ์งํํ๋ค. ์์ ๊ทธ๋ฆผ์์ ์์ด ์น ํด์ ธ์๋ ์์๋ค์ ์์๋๋ก ํฉ์น๋ฉด ๋๋ค.
ํต ์ ๋ ฌ์ ๋ถํ ์ ๋ณต ์๊ณ ๋ฆฌ์ฆ ์ค ํ๋์ด๋ค. pivot์ผ๋ก 2๊ฐ์ ๋ถ๋ถ ๋ฐฐ์ด์ ์์ฑํ๋ ๋ถํ (Divide) ๊ณผ์ ๊ณผ ๋ถ๋ถ ๋ฐฐ์ด์ ์ฌ๊ท์ ์ผ๋ก ํธ์ถํ๋ ์ ๋ณต(Conquer) ๊ณผ์ ๊ณผ ์ ๋ ฌ๋ ๋ถ๋ถ ๋ฐฐ์ด์ ํฉ๋ณํ๋ ๊ฒฐํฉ(Combine)๊ณผ์ ์ด ์กด์ฌํ๋ค.
(๋ถํ ์ ๋ณต)
๊ตฌํ
์์ฌ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
function quicksort(left, right):
pivot := arr[left]
low := left+1
high := right
while low < high:
pivot๋ณด๋ค ํฐ ์์๋ฅผ ๊ฐ์ง index ์ฐพ๊ธฐ => low
pivot๋ณด๋ค ์์ ์์๋ฅผ ๊ฐ์ง index ์ฐพ๊ธฐ => high
arr[low]์ arr[high] ๊ตํ
high์ pivot ๊ตํ
end
c++๋ก ๊ตฌํํ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
void quickSort(int* arr, int left, int right) {
if (right - left <= 1)
return;
int pivot = arr[left];
int low = left+1;
int high = right-1;
while (1) {
while(low<right){
if (arr[low] > pivot)
break;
else
low++;
}
while(high>left){
if (arr[high] < pivot)
break;
else
high--;
}
if (low >= high)
break;
swap(arr, low, high);
}
swap(arr, left, high);
quickSort(arr, left, high);
quickSort(arr, high + 1, right);
}
์๊ฐ ๋ณต์ก๋
์ต์ ๊ณผ ์ต์ ์ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด๋ณด์.
ํต ์ ๋ ฌ์์ ์ต์ ์ ๊ฒฝ์ฐ๋ ๋ถํ ๋๋ ๋ ๋ถ๋ถ ๋ฆฌ์คํธ๊ฐ ํฌ๊ธฐ๊ฐ ๋น์ทํ ๋์ผ ๊ฒ์ด๋ค. ์ต์ ์ ๊ฒฝ์ฐ์์ ๋ฆฌ์คํธ์ ๊ธธ์ด๊ฐ 1/2๋ก ์ค์ด๋ ๋ค๊ณ ํ์ ๋, 1์ด ๋๊ธฐ๊น์ง lgn๋ฒ์ ๋ถํ ์ด ํ์ํ๋ค. ๋ํ ๊ฐ ๋จ๊ณ๋ง๋ค ๋ฆฌ์คํธ๋ค์ด low, high๋ฅผ ์์ง์ด๋ฉฐ pivot๊ณผ ๋น๊ตํ๋ ํ์๋ ํฉ์ณ๋ณด๋ฉด n์ ๋น๋กํ๋ค. ๋ฐ๋ผ์ ๋น๊ตํ์๋ O(nlgn)
์ด๋ค. ์ด๋ ํ์๋ ๋น๊ตํ์์ ๋นํด์ ์ ์ผ๋ฏ๋ก ๊ณ ๋ คํ์ง ์๋๋ค.
ํ ์ชฝ์ผ๋ก ์น์ฐ์น๋ ์ต์
์ ๊ฒฝ์ฐ์๋ pivot๊ณผ ๋ค๋ฅธ ๋ชจ๋ ์์๋ฅผ ๋น๊ตํ์ฌ ๊ฐ์ฅ ํฐ(or ์์) ์์๋ฅผ ๊ฑฐ๋ฅด๋ ์ ํ ์ ๋ ฌ๊ณผ ๊ฐ์ ์์์ ๋๋ฏ๋ก ์๊ฐ๋ณต์ก๋๊ฐ O(n^2)
์ด๋ค.
์ด๋ฌํ ๊ฒฝ์ฐ๋ฅผ ๋ง๊ธฐ ์ํด pivot์ ๋๋ค์ผ๋ก ์ ํ๊ฑฐ๋ ์ฃผ์ด์ง ๋ฆฌ์คํธ๋ฅผ ๋ฌด์์๋ก ์์ ํ ์ ๋ ฌ์ ์งํํ๊ธฐ๋ ํ๋ค.
๊ทธ๋ ๋ค๋ฉด ํ๊ท ์๊ฐ ๋ณต์ก๋๋ ์ด๋ป๊ฒ ์ ์ ์์๊น?
(ํ์์๋ค๋ฉด ์คํตํด๋ ๋๋ค.)
์์ ๊ฐ์ด pivot์ ๋ํด ์ผ์ชฝ ์ค๋ฅธ์ชฝ์ผ๋ก ์์๋ค์ ์ ๋ฆฌํ๊ณ ๋๋ฉด, ๋ฆฌ์คํธ์์์ pivot ์์น๊ฐ ๋๋ฌ๋๊ฒ ๋๋๋ฐ ๋ฆฌ์คํธ๋ฅผ ๋ ๋ถ๋ฅ๋ก ๋๋ ์(split) ์๋ค๋ ๋ป์์ ์ด๋ฅผ splitpoint๋ผ๊ณ ํ๋ค.
$$
A(n) = n-1 + \sum \frac{1}{n}(A(i-1) + A(n-i))
$$
splitpoint๊ฐ i์ผ ๋์ ๋น๊ตํ์๋ splitpoint๋ฅผ ์ฐพ๊ธฐ ์ํด ๋ค๋ฅธ ์์๋ค๊ณผ ๋น๊ตํ๋ n-1๋ฒ์๋ค๊ฐ ์ฌ๊ท์ ์ผ๋ก ์ผ์ชฝ i-1๊ฐ๋ฅผ ํต ์ ๋ ฌํ๋๋ฐ์ ํ์ํ ํ๊ท ๋น๊ตํ์, ์ค๋ฅธ์ชฝ n-i๊ฐ๋ฅผ ํต ์ ๋ ฌํ๋๋ฐ์ ํ์ํ ํ๊ท ๋น๊ตํ์๋ฅผ ๋ํ ๊ฒ๊ณผ ๊ฐ๋ค. ๋ฐ๋ผ์ splitpoint๋ฅผ 1๋ถํฐ n๊น์ง ์ฎ๊ฒจ๊ฐ๋ฉฐ ํ๊ท ๋น๊ตํ์๋ฅผ ๋ํ๊ณ ๊ฒฝ์ฐ์ ์ n์ผ๋ก ๋๋์ด์ฃผ๋ฉด ์์ ๊ฐ์ ์์ด ์์ฑ๋๋ค.
$$
\sum_{i=1}^{n}(A(i-1)+A(n-i))
$$
์ด ์์ ํ์ด์ธ ๊ฒฝ์ฐ์
์ด๋ฏ๋ก
$$
\sum_{i=0}^{n-1}2A(i)
$$
์ด๋ค.
๊ทธ๋ ๋ค๋ฉด ์ต์ข ์ ์ผ๋ก
$$
A(n) = n-1 + \sum_{i=0}^{n-1}2A(i)
$$
๋ผ๋ ์์ด ๋์ค๊ฒ ๋๋๋ฐ, ์ด ์์ด ์ต์ ์ ๊ฒฝ์ฐ์ ๊ฐ๊น์ด์ง ์ต์
์ ๊ฒฝ์ฐ์ ๊ฐ๊น์ด์ง๋ฅผ ์ํ์ ๊ท๋ฉ๋ฒ์ผ๋ก ํ๋จํด๋ณด์.
๋ฐ๋ผ์ ํ๊ท ์๊ฐ๋ณต์ก๋๋ ์ต์ ์ ์๊ฐ๋ณต์ก๋์ ๊ฐ๊น์ด O(nlgn)์ด๋ค.
ํน์ง
- ์ฐฐ์ค ์คํฐ๋ ๋ฆฌ์ฒ๋ ํธ์ด๊ฐ ๊ฐ๋ฐํ๋ค.
- ๋ถ์์ ์ ๋ ฌ์ด๋ค.
- ๋น๊ต ์ ๋ ฌ์ด๋ค.
- ํ๊ท ์ ์ผ๋ก ๊ฐ์ฅ ๋น ๋ฅธ ์ ๋ ฌ ๋ฐฉ๋ฒ์ด๋ค.
- ๋ถํ ์ ๋ณต ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ค.
- ์ดํ ๋์ฌ ํฉ๋ณ ์ ๋ ฌ, ํ ์ ๋ ฌ์ด ํญ์ O(nlgn)์ธ ๊ฒ์ ๋ฐํด ํต ์ ๋ ฌ์ ํ๊ท ์๊ฐ๋ณต์ก๋๊ฐ O(nlgn)์ด๋ค.
ํฉ๋ณ ์ ๋ ฌ
๊ฐ๋
ํฉ๋ณ ์ ๋ ฌ ๋ํ ํต ์ ๋ ฌ๊ณผ ๊ฐ์ด ๋ถํ ์ ๋ณต ๊ธฐ๋ฒ์ ์ฌ์ฉํ ์ ๋ ฌ์ด๋ค. ํฉ๋ณ ์ ๋ ฌ์ ์ธ๋ถ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
๋จผ์ ์ฃผ์ด์ง ๋ฐฐ์ด์ ๋ถํ ํ๋ค.
๋ถํ ๋ ๊ฐ๊ฐ์ ์์๋ค์ ๋น๊ตํ์ฌ ํฉ๋ณ(์ ๋ณต)ํ๋ค.
ํฉ๋ณ์ ์ธ๋ถ ๊ณผ์ ์ ์์ ๊ฐ๋ค. A, B ๋ ๋ฆฌ์คํธ๋ฅผ ํฉ๋ณํ๋ค๊ณ ํ์ ๋ ๊ฐ๊ฐ์ ๋ฆฌ์คํธ์ ํฌ์ธํฐ๋ฅผ ๋๋ค. ํฌ์ธํฐ์ ์์๋ฅผ ๋น๊ตํ์ฌ ์์ ์์ผ๋ก ์๋ก์ด ๋ฐฐ์ด C์ ์ ์ฅํ๊ณ , ํ ๋ฐฐ์ด์ ๋ชจ๋ ์์๋ฅผ ๋ชจ๋ ์ ์ฅํ๋ค๋ฉด ๋ค๋ฅธ ๋ฐฐ์ด์ ๋จ์ ์์๋ฅผ C์ ์ ์ฅํ๋ค. ์์์๋ A์ ์์๊ฐ ๋จผ์ ๋ชจ๋ ์ ์ฅ๋์๊ธฐ ๋๋ฌธ์ ๊ทธ ํ, B์ ๋จ์ ์์๋ค์ C์ ์ ์ฅํ๋ค.
๊ตฌํ
์์ฌ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
function merge(left, mid, right):
l:=left
r:=right
sorted := []
while l<mid+1 && r<right:
if arr[l]<arr[r]:
sorted์ arr[l++] ๋ฃ๊ธฐ
else
sorted์ arr[r++] ๋ฃ๊ธฐ
๋จ์ ๋ฐฐ์ด sorted์ ๋ฃ๊ธฐ
sorted ๋ฐฐ์ด arr[left,right]์ ์ ์ฅ
end
function mergesort(left, right):
if left==right:
return;
mid:= (left+right)/2
mergesort(left,mid);
mergesort(mid+1,right);
merge(left, mid, right);
end
c++๋ก ๊ตฌํํ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
void merge(int* arr, int left, int mid, int right) {
int l = left; int r = mid;
int* sorted = (int*)malloc(sizeof(int)*(right - left));
int index = 0;
while (l < mid && r < right) {
if (arr[l] < arr[r])
sorted[index++] = arr[l++];
else
sorted[index++] = arr[r++];
}
// ๋จ์ ๋ฐฐ์ด ๋ฃ๊ธฐ
if (l >= mid) {
// ์ผ์ชฝ ๋ฐฐ์ด์ ๋ค ๋ฃ์์ผ๋ฉด
for (int i = r; i < right; i++)
sorted[index++] = arr[i];
}
else if(r >= right){
// ์ค๋ฅธ์ชฝ ๋ฐฐ์ด์ ๋ค ๋ฃ์์ผ๋ฉด
for (int i = l; i < mid; i++)
sorted[index++] = arr[i];
}
// sorted => arr
for (int i = 0; i < right-left; i++) {
arr[i+left] = sorted[i];
}
}
void mergeSort(int* arr, int left, int right) {
if (right-left<=1) // ์์๊ฐ ํ๋์ด๋ฉด return
return;
int mid = (int)((left + right) / 2);
mergeSort(arr, left, mid);
mergeSort(arr, mid, right);
merge(arr, left, mid, right);
}
์๊ฐ ๋ณต์ก๋
ํฉ๋ณ ๋จ๊ณ์์ n๋งํผ์ ์์๋ฅผ ํ์ผ๋ฉด์ ๋น๊ตํ๊ณ ํฉ์น๋ ๊ณผ์ ์ lgn ๋จ๊ณ๋งํผ ๋ฐ๋ณตํ๋ค. ๋ฐ๋ผ์ ๋น๊ต์ ์๊ฐ๋ณต์ก๋๋ O(nlgn)
์ด๋ค. ์ด๋์ ๊ธฐ์กด ๋ฐฐ์ด์์ ์๋ก์ด ๋ฐฐ์ด์ผ๋ก ์์๋ค์ ์ฎ๊ธฐ๋ ๊ณผ์ ๊ณผ ์๋ก์ด ๋ฐฐ์ด์์ ๊ธฐ์กด ๋ฐฐ์ด๋ก ์์๋ค์ ์ฎ๊ธฐ๋ ๊ณผ์ ์ ์ํด 2n๋ฒ ๋ฐ์ํ๊ณ , ์ด๋ฅผ lgn ๋จ๊ณ๋งํผ ๋ฐ๋ณตํ๋ฏ๋ก ์ด๋์ ์๊ฐ๋ณต์ก๋๋ O(2nlgn)
์ด๋ค.
๋ฐ๋ผ์ ํฉ๋ณ ์ ๋ ฌ์ ์ด ์๊ฐ ๋ณต์ก๋๋ O(nlgn)์ด๋ฉฐ ์ต์ , ์ต์ , ํ๊ท ์์ ํฐ ์ฐจ์ด ์์ด ๋น์ทํ๋ค.
ํต ์ ๋ ฌ๊ณผ ๋น๊ตํด์ ์๊ฐํด๋ณด๋ฉด ๋ถํ ๊ณผ์ ์์ ์ ๋ฆผํ์ ์์ด ๊ท ๋ฑํ๊ฒ ๋ถ๋ฐฐ๋๋ฏ๋ก ํญ์ ํต ์ ๋ ฌ์ ์ต์ ์ ๊ฒฝ์ฐ์ ๊ฐ๋ค. ์์ผ๋ก ๋ํ๋ด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
$$
O(n) = O(\lceil\frac{n}{2}\rceil)+O(\lfloor\frac{n}{2}\rfloor)+ n-1
$$
ํน์ง
- ํต ์ ๋ ฌ๊ณผ ๋น๊ตํ์ฌ ์ต์ ์ ์๊ฐ๋ณต์ก๋๋ O(nlgn)์ด๋ค.
- ํ์ง๋ง ๊ณต๊ฐ๋ณต์ก๋๊ฐ O(n)์ผ๋ก ํฐ ํธ์ด๋ค.
- ์์ ์ ๋ ฌ์ด๋ค.
- ์ด๊ธฐ ๋ฐ์ดํฐ ์ํ์ ์ํฅ์ ๋ ๋ฐ๋๋ค.
Comment