ํต ์ ๋ ฌ(Quick Sort)๊ณผ ๋์ผ ํผ๋ด ํต ์ ๋ ฌ(Dual Pivot Quick Sort)
ํต ์ ๋ ฌ์ ๊ฐ๋
์์์ ํผ๋ด(pivot)์ ๊ธฐ์ค์ผ๋ก ํด๋น ํผ๋ด ๊ฐ๋ณด๋ค ์์ ๋ฐ์ดํฐ๋ ํผ๋ด์ ์ผ์ชฝ์, ํฐ ๋ฐ์ดํฐ๋ ํผ๋ด์ ์ค๋ฅธ์ชฝ์ ๋ฐฐ์นํ ๋ค, ์ผ์ชฝ ๋ถ๋ถ๊ณผ ์ค๋ฅธ์ชฝ ๋ถ๋ถ์ ๋ค์ ํต ์ ๋ ฌ ๋ฐฉ๋ฒ์ผ๋ก ์ ๋ ฌํ๋ ์๊ณ ๋ฆฌ์ฆ
์ ์ฒด ๋ฐ์ดํฐ๋ฅผ 2๊ฐ์ ๋ถ๋ถ์ผ๋ก ๋ถํ ํ ๋ค, ๊ฐ๊ฐ์ ๋ถ๋ถ์ ๋ค์ ํต์ ๋ ฌํ๋ ์ ํ์ ์ธ ๋ถํ -์ ๋ณต ์๊ณ ๋ฆฌ์ฆ
์๋ฆฌ
quick_sort(int[] list, int left, int right) {
if (left < right) {
int pivot = partition(list, left, right);
quick_sort(list, left, pivot-1);
quick_sort(list, pivot+1, right);
}
}
ํผ๋ด์ ๊ธฐ์ค์ผ๋ก ๋ถํ ํ๊ธฐ
ํต ์ ๋ ฌ ๊ตฌํ์ ํต์ฌ์ ์ ์๊ณ ๋ฆฌ์ฆ์ partition()
๋ถ๋ถ์ธ ์ ์ฒด ๋ฐฐ์ด์ ํผ๋ด์ ๊ธฐ์ค์ผ๋ก ๋ ๋ถ๋ถ์ผ๋ก ๋ถํ ํ๋ ๊ฒ์ด๋ค. ๋ถํ ์ ์๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ๋ฐฐ์ด์ ์์์ ์์๋ฅผ
pivot
, ๊ฐ์ฅ ์ฒซ๋ฒ์งธ ์์๋ฅผlow
, ๊ฐ์ฅ ๋ง์ง๋ง ์์๋ฅผhigh
์ด๋ผ๊ณ ์ง์ ํ๋ค.low
๊ฐ์ดpivot
๋ณด๋ค ์์ ๋์low
์ธ๋ฑ์ค๋ฅผ ์ฆ๊ฐ์ํจ๋ค. ๋ฐ๋ณต๋ฌธ์ด ๊ณ์๋ ๋๊น์ง ์กฐ๊ฑด์ ๋ถํฉํ๋ ์์๋ค์pivot
์ ์ผ์ชฝ ๋ถ๋ถ ๋ฆฌ์คํธ๊ฐ ๋๋ค.high
๊ฐ์ดpivot
๋ณด๋ค ํด ๋์high
์ธ๋ฑ์ค๋ฅผ ๊ฐ์์ํจ๋ค. ๋ฐ๋ณต๋ฌธ์ด ๊ณ์๋ ๋๊น์ง ์กฐ๊ฑด์ ๋ถํฉํ๋ ์์๋ค์pivot
์ ์ค๋ฅธ์ชฝ ๋ถ๋ถ ๋ฆฌ์คํธ๊ฐ ๋๋ค.- 2์ 3์ ๋ฐ๋ณต๋ฌธ์ ํ์ถํ์ฌ ๋๋ฌํ ์์น๋ ๊ฐ๊ฐ
low
๊ฐ์ดpivot
๋ณด๋ค ํฌ๊ณ ,high
๊ฐ์ดpivot
๋ณด๋ค ์์ ๊ฒฝ์ฐ์ด๋ฏ๋ก, ์ด ๋ ๋ฉ์ถ ๋ ์์ ์๋ฆฌ๋ฅผ ๊ตํํ๋ค.low
์high
์ ์์น๊ฐ ์๊ฐ๋ฆฌ์ง ์์ ๋๊น์ง 2~3์ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค.low
์high
์ ์์น๊ฐ ์๊ฐ๋ฆฌ๋ ๋high
์pivot
์ ์๋ฆฌ๋ฅผ ๊ตํํ๋ค. ์ต์ข ์ ์ผ๋กpivot
์ ์์น๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ์๋pivot
๋ณด๋ค ์์ ์์๋ค์ด, ์ค๋ฅธ์ชฝ์๋pivot
๋ณด๋ค ํฐ ์์๋ค์ด ์์นํ๊ฒ ๋๋ค.
ํต ์ ๋ ฌ ์๊ฐ ๋ณต์ก๋
- ๋ถํ
n๊ฐ์ ์์๋ฅผ ๊ฐ์ง ๋ฐฐ์ด์ ์ ๋ ฌํ๋ค๊ณ ํ๋ฉด, ๋ฐฐ์ด์ ๊ฐ ๋จ๊ณ์์
partition()
์ ๊ฑฐ์น ๋๋ง๋คn/2
,n/4
,n/8
โฆ,n/(2^k)
์ ํฌ๊ธฐ๋ก ๋ถํ ๋๋ค. ์ด ๊ณผ์ ์ ๋ฐฐ์ด์ ์์ ๊ฐ์๊ฐ 1๊ฐ๊ฐ ๋ ๋๊น์ง ๋ฐ๋ณต๋๋ฏ๋กn/(2^k) = 1
์ผ ๋๊น์ง ๋ฐ๋ณต๋๋ค. ๋ฐ๋ผ์k = log n
๋งํผ์ ์ฐ์ฐ์ด ์ํ๋๋ค. - ์์ ๊ตํ
๊ฐ ์ผ์ชฝ ๋ถ๋ถ์ ์ค๋ฅธ์ชฝ ๋ถ๋ถ์์๋ ๊ตํ์ ์ํด ๊ฑฐ์ ๋ถ๋ถ์ ๋ชจ๋ ์์๋ค์ ํ์ธํด์ผ ํ๋ฏ๋ก ๊ฐ ๋ถ๋ถ์ ์์ ๊ฐ์๋งํผ(
n
) ์ฐ์ฐ์ด ์ํ๋๋ค.
์ ๊ณ์ฐ ๊ฒฐ๊ณผ ์ต์ข
์ ์ผ๋ก ํ๊ท O(n log n)
์ ์๊ฐ๋ณต์ก๋๋ฅผ ๋ณด์ด๊ฒ ๋๋ค.
ํ์ง๋ง ๋งค๋ฒ ๋จ ํ๋์ ์์๋ฅผ ๊ฐ์ง ๋ถ๋ถ์ ๋๋จธ์ง ์์๋ค์ ๊ฐ์ง ๋ถ๋ถ์ผ๋ก ๋๋๋ ๊ฒฝ์ฐ ๋ฑ, ๋ฐฐ์ด์ ์ด๊ธฐ๊ฐ์ด๋ ํผ๋ด์ ์ ํ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ์ต์
์ ๊ฒฝ์ฐ O(n^2)
์ ์๊ฐ ๋ณต์ก๋๋ฅผ ๋ณด์ผ ์ ์๋ค.
๊ตฌํ
class QuickSort {
static int left; // ์ผ์ชฝ ์ปค์
static int right; // ์ค๋ฅธ์ชฝ ์ปค์
static int pivot; // ํผ๋ด
// ์์ ๊ตํ
static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// ๋ถํ
static void partition(int[] arr, int low, int high) {
left = low; // ์ผ์ชฝ ์ปค์
right = high; // ์ค๋ฅธ์ชฝ ์ปค์
pivot = arr[(left+right)/2]; // ํผ๋ด
do {
while(arr[left] < pivot) left++;
while(arr[right] > pivot) right--;
if (left <= right) swap(arr, left++, right--);
} while(left <= right);
}
// ํต ์ ๋ ฌ
static void quickSort(int[] arr, int low, int high) {
partition(arr, low, high);
if (low < right) quickSort(arr, low, right);
if (left < high) quickSort(arr, left, high);
}
}
๋์ผ ํผ๋ด ํต ์ ๋ ฌ(Dual Pivot Quick Sort)
ํผ๋ด 1๊ฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ์ ์ ๋ ฌํ๋ ํต ์ ๋ ฌ์์ ๋์๊ฐ ํผ๋ด 2๊ฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๋ ์๊ณ ๋ฆฌ์ฆ
์์์ ํผ๋ด 2๊ฐ๋ฅผ ๊ธฐ์ค์ผ๋ก pivot1
๋ณด๋ค ์์ ๋ถ๋ถ, pivot1
~ pivot2
์ฌ์ด์ ๋ถ๋ถ, pivot2
๋ณด๋ค ํฐ ๋ถ๋ถ์ผ๋ก ๋๋ ๋ค ๊ฐ ๋ถ๋ถ์ ๋ค์ ๋์ผ ํผ๋ด ํต ์ ๋ ฌ ๋ฐฉ๋ฒ์ผ๋ก ์ ๋ ฌํ๋ค.
pivot2
๋ ํญ์ pivot1
๋ณด๋ค ํฌ๋๋ก ์ค์ ํด์ผํจ์ ์ฃผ์ํ๋ค.
๋์ผ ํผ๋ด ํต ์ ๋ ฌ ์๊ฐ ๋ณต์ก๋
ํต ์ ๋ ฌ๊ณผ ๋ฌ๋ฆฌ 3๋ถ๋ถ์ผ๋ก ๋๋๊ธฐ๋๋ฌธ์ ฮ(nlog3n)
์ ๋์ ์ฐ์ฐ์ด ๊ธฐ๋๋๋ค. ํ์ง๋ง ์ต์
์ ๊ฒฝ์ฐ์๋ ํต ์ ๋ ฌ๊ณผ ๊ฐ์ด O(n^2)
์ ์๊ฐ ๋ณต์ก๋๋ฅผ ํผํ ์ ์๋ค.