[์๊ณ ๋ฆฌ์ฆ] ์ ๋ ฌ(Sorting Algorithm)์ด๋?
์ ๋ ฌ์ด๋?
์ปดํจํฐ ๊ณผํ์์ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด๋ ์์๋ค์ ๋ฒํธ์์ด๋ ์ฌ์ ์์์ ๊ฐ์ด ์ผ์ ํ ์์๋๋ก ์ด๊ฑฐํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
- ์ค๋ฆ์ฐจ์ ์ ๋ ฌ : 1, 2, 3, ..., n-1, n
- ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ : n, n-1 ... 3, 2, 1
์๊ณ ๋ฆฌ์ฆ ๋ณต์ก๋ ๊ณ์ฐ
์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ๋งค์ฐ ๋ค์ํ๊ธฐ ๋๋ฌธ์ ๊ฐ๊ฐ์ ํจ์จ์ฑ์ ๋น๊ตํ๊ธฐ ์ํด ์๊ณ ๋ฆฌ์ฆ ๋ณต์ก๋๋ฅผ ๊ณ์ฐํฉ๋๋ค.
- ์๊ฐ ๋ณต์ก๋ : ์๊ณ ๋ฆฌ์ฆ ์คํ ์๋ (์๊ฐ ํจ์จ์ฑ)
- ๊ณต๊ฐ ๋ณต์ก๋ : ์๊ณ ๋ฆฌ์ฆ์ด ์ฌ์ฉํ๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ด์ฆ (๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ ํจ์จ์ฑ)
์ด๋ฌํ ์๊ฐ/๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ๋ํ๋ด๋ ๋ฐฉ๋ฒ์ผ๋ก ๋น ์ค(Big-O), ๋น ์ค๋ฉ๊ฐ(Big-Ω), ๋น ์ธํ(Big-Θ) ํ๊ธฐ๋ฒ์ด ์์ต๋๋ค.
๋น ์ค ํ๊ธฐ๋ฒ(big-O notation)์ด๋?
๋น ์ค ํ๊ธฐ๋ฒ์ ์๊ณ ๋ฆฌ์ฆ์ ํจ์จ์ฑ์ ํ๊ธฐํด์ฃผ๋ ๊ธฐ๋ฒ์ผ๋ก ์ํ์ ๊ธฐ์ค(์ต์ ์ ์๊ฐ)์ ์๊ฐ๋ณต์ก๋๋ฅผ ๋ํ๋ ๋๋ค.
์ ๋ ฅ n์ ๋ฐ๋ผ ๋ช๋ฒ ๊ณ์ฐ์ด ์คํ๋๋์ง๋ฅผ ํํ์์ ๊ฐ์ฅ ํฐ ์ํฅ์ ๋ฏธ์น๋ n์ ๋จ์๋ก ํ๊ธฐํ๋ฉฐ ์๊ฐ์ด ๋น ๋ฅธ์์ผ๋ก ๋์ดํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
O(1) < O(logn) < O(n) < O(nlogn) < O(n²) < O(2โฟ) < O(n!) |
*๋น ์ค๋ฉ๊ฐ๋ ํํ์ ๊ธฐ์ค, ๋น ์ธํ๋ ์ํ์ ๊ณผ ํํ์ ์ ์ฌ์ด๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๊ธฐํจ
๋ํ์ ์ธ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ
๊ตํ, ์ ํ, ์ฝ์ 3๊ฐ์ง ํต์ฌ์์๋ฅผ ํตํด ์ ๋ ฌํ๋ ๋ํ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Name | Best | Avg | Worst |
๊ฑฐํ ์ ๋ ฌ (Bubble Sort) | O(n²) | O(n²) | O(n²) |
์ ํ ์ ๋ ฌ(Selection Sort) | O(n²) | O(n²) | O(n²) |
์ฝ์ ์ ๋ ฌ(Insertion Sort) | O(n) | O(n²) | O(n²) |
ํต ์ ๋ ฌ(Quick Sort) | O(nlogn) | O(nlogn) | O(n²) |
๋ณํฉ ์ ๋ ฌ(Merge Sort) | O(nlogn) | O(nlogn) | O(nlogn) |
ํ ์ ๋ ฌ(Heap Sort) | O(nlogn) | O(nlogn) | O(nlogn) |
๊ธฐ์ ์ ๋ ฌ(Radix Sort) | O(n) | O(n) | O(n) |
๊ณ์ ์ ๋ ฌ(Counting Sort) | O(n) | O(n) | O(n) |
๊ฑฐํ ์ ๋ ฌ (Bubble Sort)
๋ฒ๋ธ ์ ๋ ฌ์ ์๋ก ์ธ์ ํ ๋ ์์๋ฅผ ๋น๊ตํ์ฌ, ์กฐ๊ฑด์ ๋ง์ง ์๋ค๋ฉด ์๋ฆฌ๋ฅผ ๊ตํํ๋ฉฐ ์ ๋ ฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
(์ ๋ ฌ ๊ณผ์ ์์ ์์์ ์ด๋์ด ๊ฑฐํ์ด ์๋ฉด์ผ๋ก ์ฌ๋ผ์ค๋ ๋ฏํ ๋ชจ์ต์ ๋ณด์ด๊ธฐ ๋๋ฌธ์ ๋ฒ๋ธ์ ๋ ฌ์ด๋ผ๋ ์ด๋ฆ์ด ์ง์ด์ง)
- ์๊ฐ ๋ณต์ก๋ : O(n²)
- ๊ณต๊ฐ ๋ณต์ก๋ : O(n)
- ์ฅ๋จ์ : ๊ตฌํ์ด ์ฝ์ง๋ง ๋นํจ์จ์
์๋์ ๊ฐ์ด 0๋ฒ index๋ถํฐ n-1๋ฒ index๊น์ง n๋ฒ๊น์ง์ ๋ชจ๋ index๋ฅผ ๋น๊ตํ๋ฉฐ ์ ๋ ฌํฉ๋๋ค.
function bubbleSort (arr) {
for(let i = 0; i < arr.length; i++) {
for(let j = 0; j < arr.length -1 - i; j++) {
if(arr[j] > arr[j + 1]) {
let swap = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = swap
}
}
}
return arr
}
์ ํ ์ ๋ ฌ(Selection Sort)
์ ํ ์ ๋ ฌ์ ํด๋น ์์์ ์์๋ฅผ ๋ฃ์ ์์น๋ ์ด๋ฏธ ์ ํด์ ธ ์๊ณ , ์ด๋ค ์์๋ฅผ ๋ฃ์์ง ์ ํํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
- ์๊ฐ ๋ณต์ก๋ : O(n²)
- ๊ณต๊ฐ ๋ณต์ก๋ : O(n)
- ์ฅ๋จ์ : ๊ตฌํ์ด ์ฝ์ง๋ง ๋นํจ์จ์ , ๋ฒ๋ธ๋ณด๋ค ์ฝ๊ฐ ๋น ๋ฆ
์๋์ ๊ฐ์ด ์ฒซ ๋ฒ์งธ ๊ฐ์ ๋ ๋ฒ์งธ ๋ถํฐ ๋ง์ง๋ง ๊ฐ๊น์ง ์ฐจ๋ก๋๋ก ๋น๊ตํ์ฌ ์ต์๊ฐ์ ์ฐพ์ ์ฒซ ๋ฒ์งธ์ ๋๊ณ , ๋ ๋ฒ์งธ ๊ฐ์ ์ธ ๋ฒ์งธ ๋ถํฐ ๋ง์ง๋ง ๊ฐ๊น์ง ๋น๊ตํ์ฌ ์ต์๊ฐ์ ์ฐพ์ ๋ ๋ฒ์งธ ์์น์ ๋๋ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ฉฐ ์ ๋ ฌํฉ๋๋ค.
function selectSort (arr) {
for(let i = 0; i < arr.length; i++) {
let min = i
for(let j = i + 1; j < arr.length; j++) {
if(arr[min] > arr[j]) {
min = j
}
}
if(min !== i) {
let swap = arr[min]
arr[min] = arr[i]
arr[i] = swap
}
}
return arr
}
์ฝ์ ์ ๋ ฌ(Insertion Sort)
์ฝ์ ์ ๋ ฌ์ ๋ ๋ฒ์งธ ์์๋ถํฐ ์์ํ์ฌ ๊ทธ ์(์ผ์ชฝ)์ ์์๋ค๊ณผ ๋น๊ตํ์ฌ ์ฝ์ ํ ์์น๋ฅผ ์ง์ ํ ํ, ์์๋ฅผ ๋ค๋ก ์ฎ๊ธฐ๊ณ ์ง์ ๋ ์๋ฆฌ์ ์๋ฃ๋ฅผ ์ฝ์ ํ์ฌ ์ ๋ ฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
- ์๊ฐ ๋ณต์ก๋ : O(n) (์ต์ ์ ๊ฒฝ์ฐ O(n²) )
- ๊ณต๊ฐ ๋ณต์ก๋ : O(n)
- ์ฅ๋จ์ : ์ฑ๋ฅ์ด ์ข์์ ๋ค๋ฅธ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ ์ผ๋ถ๋ก ์ฌ์ฉ๋๊ธฐ๋ ํจ, ๋ฐ์ดํฐ ์ํ๋ ํฌ๊ธฐ์ ๋ฐ๋ผ ํธ์ฐจ๊ฐ ์ฌํจ
function insertionSort(arr) {
for(let i = 1; i < arr.length; i ++) {
let cur = arr[i]
let left = i - 1
while(left >= 0) {
if(arr[left] > arr[left + 1]) {
arr[left + 1] = arr[left]
arr[left] = cur
}
left--
}
}
return arr
}
ํต ์ ๋ ฌ(Quick Sort)
ํต ์ ๋ ฌ์ ๋ถํ ์ ๋ณต ๋ฐฉ๋ฒ์ ํตํด ์ฃผ์ด์ง ๋ฐฐ์ด์ ์ ๋ ฌํฉ๋๋ค.
- ์๊ฐ ๋ณต์ก๋ : O(nlogn) (์ต์ ์ ๊ฒฝ์ฐ O(n²) )
- ๊ณต๊ฐ ๋ณต์ก๋ : O(n)
- ์ฅ๋จ์ : ๋งค์ฐ ๋น ๋ฅด์ง๋ง ์ต์ ์ ํผ๋ด์ ์ ํํ ๊ฒฝ์ฐ ์๊ฐ๋ณต์ก๋๊ฐ ๋ง์ด ๋์ด๋จ
์๋์ ๊ฐ์ด ํผ๋ด์ ์ค์ ํ๊ณ ํผ๋ด๋ณด๋ค ํฐ ๊ฐ๊ณผ ์์ ๊ฐ์ผ๋ก ๋ถํ ํ์ฌ ์ ๋ ฌํฉ๋๋ค. ๋ณํฉ ์ ๋ ฌ๊ณผ ๋ฌ๋ฆฌ ๋ฐฐ์ด์ ๋น๊ท ๋ฑํ๊ฒ ๋ถํ ํ๋ค๋ ํน์ง์ด ์์ต๋๋ค.
function quickSort(arr) {
if(arr.length <= 1) {
return arr
}
let cur = arr[0]
let left = []
let right = []
for(let i = 1; i < arr.length; i++) {
if(cur > arr[i]) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
let leftArr = quickSort(left)
let rightArr = quickSort(right)
return [...leftArr, cur, ...rightArr]
}
๋ณํฉ ์ ๋ ฌ(Merge Sort)
๋ณํฉ ์ ๋ ฌ์ ํฉ๋ณ ์ ๋ ฌ์ด๋ผ๊ณ ๋ ๋ถ๋ฅด๋ฉฐ, ๋ถํ /์ ๋ณต ๋ฐฉ๋ฒ์ ํตํด ๊ตฌํํฉ๋๋ค.
- ์๊ฐ ๋ณต์ก๋ : O(nlogn)
- ๊ณต๊ฐ ๋ณต์ก๋ : O(n)
- ์ฅ๋จ์ : ํต ์ ๋ ฌ๊ณผ ๋ฌ๋ฆฌ ํผ๋ด์ ์ค์ ํ์ง ์์ ๊ธฐ๋ณต์ด ์์, ์ถ๊ฐ์ ์ธ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํ๋ ๋จ์ ์ด ์์
์๋์ ๊ฐ์ด ์ฃผ์ด์ง ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ 1์ธ ๋ฐฐ์ด๋ก ๋ถํ ํ๊ณ ํฉ๋ณํ๋ฉด์ ์ ๋ ฌ์ ์งํํ๋ ๋ถํ /์ ๋ณต ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
private void solve() {
int[] array = { 230, 10, 60, 550, 40, 220, 20 };
mergeSort(array, 0, array.length - 1);
for (int v : array) {
System.out.println(v);
}
}
public static void mergeSort(int[] array, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(array, left, mid);
mergeSort(array, mid + 1, right);
merge(array, left, mid, right);
}
}
public static void merge(int[] array, int left, int mid, int right) {
int[] L = Arrays.copyOfRange(array, left, mid + 1);
int[] R = Arrays.copyOfRange(array, mid + 1, right + 1);
int i = 0, j = 0, k = left;
int ll = L.length, rl = R.length;
while (i < ll && j < rl) {
if (L[i] <= R[j]) {
array[k] = L[i++];
} else {
array[k] = R[j++];
}
k++;
}
while (i < ll) {
array[k++] = L[i++];
}
while (j < rl) {
array[k++] = R[j++];
}
}
ํ ์ ๋ ฌ(Heap Sort)
ํ ์ ๋ ฌ์ *์์ ์ด์ง ํธ๋ฆฌ๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ํ๋ ํ ์๋ฃ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ๋ ฌํ๋ ๋ฐฉ์์ ๋๋ค.
- ์๊ฐ ๋ณต์ก๋ : O(nlogn)
- ๊ณต๊ฐ ๋ณต์ก๋ : O(n)
- ์ฅ๋จ์ : ์ถ๊ฐ์ ์ธ ๋ฉ๋จธ๋ฆฌ๋ฅผ ํ์๋ก ํ์ง ์์, ๋ฐ์ดํฐ ์ํ์ ๋นํด ๋ค๋ฅธ ์ ๋ ฌ๋ณด๋ค ๋๋ฆฐ ๊ฒฝ์ฐ๊ฐ ์์
*์์ ์ด์ง ํธ๋ฆฌ : ์ฝ์ ํ ๋ ์ผ์ชฝ๋ถํฐ ์ฐจ๋ก๋๋ก ์ถ๊ฐํ๋ ์ด์ง ํธ๋ฆฌ
์๋์ ๊ฐ์ด ์ฃผ์ด์ง ๋ฐ์ดํฐ๋ฅผ ํ ์๋ฃ๊ตฌ์กฐ๋ก ๋ง๋ค์ด ์ต๋๊ฐ ๋๋ ์ต์๊ฐ๋ถํฐ ํ๋์ฉ ๊บผ๋ด์ ์ ๋ ฌํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๋๋ค.
private void solve() {
int[] array = { 230, 10, 60, 550, 40, 220, 20 };
heapSort(array);
for (int v : array) {
System.out.println(v);
}
}
public static void heapify(int array[], int n, int i) {
int p = i;
int l = i * 2 + 1;
int r = i * 2 + 2;
if (l < n && array[p] < array[l]) {
p = l;
}
if (r < n && array[p] < array[r]) {
p = r;
}
if (i != p) {
swap(array, p, i);
heapify(array, n, p);
}
}
public static void heapSort(int[] array) {
int n = array.length;
// init, max heap
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(array, n, i);
}
// for extract max element from heap
for (int i = n - 1; i > 0; i--) {
swap(array, 0, i);
heapify(array, i, 0);
}
}
public static void swap(int[] array, int a, int b) {
int temp = array[a];
array[a] = array[b];
array[b] = temp;
}
[์ฐธ๊ณ ]
https://ko.wikipedia.org/wiki/%EC%A0%95%EB%A0%AC_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98
https://velog.io/@msriver/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%A0%95%EB%A0%AC%EC%9D%B4%EB%9E%80
https://noahlogs.tistory.com/27