๋ถ๋ฅ
๋น๊ต ํ์์ ์ํด
- ๋น๊ต์ ๊ธฐ๋ฐํ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์์๋ ์ต์ ์ ๊ฒฝ์ฐ , ์ต์
์ ๊ฒฝ์ฐ .
๊ตํSwap ํ์์ ์ํด
๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ํด - ์ด๋ค ์๊ณ ๋ฆฌ์ฆ์ ์ ์๋ฆฌ(in-place)์์ ์ํ๋๋ฏ๋ก ๋ฐ์ดํฐ๋ฅผ ์์์ ์ผ๋ก ์ ์ฅํ ๋ณด์กฐ ๊ณต๊ฐ์ ์ํด O(1)์ด๋ O(logn) ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํ๋ค.
์ฌ๊ท์ ์ํด
์์ ์ฑ์ ์ํด
์ ์์ฑAdaptability ์ ์ํด - ์ด๋ค ์๊ณ ๋ฆฌ์ฆ๋ค์ ์ ์ ๋ ฌpresortedness ์ ์ํด ๋ณต์ก๋๊ฐ ๋ฐ๋๋ค.
๋ํ์ ์ธ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ๋ค
๋ฒ๋ธ ์ ๋ ฌ Bubble Sort
void BubbleSort(int arr[], int len) {
int i, j, tmp;
for (i = 0; i < len - 1; ++i) {
for (j = 0; j < len - i - 1; ++j) {
if (arr[j] > arr[j + 1]) {
tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
void BubbleSort(int arr[],int len){
int pass, i, temp, swappted = 1;
for(pass=len-1;pass>=0 && swapped;pass--){
swapped = 0;
for(i=0;i<pass;i++){
if(arr[i] > arr[i+1]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
swapped = 1;
}
}
}
}
์๋์ ๋ฒ๋ธ ์ ๋ ฌ์ ์กฐ๊ธฐ ์ข ๋ฃ ์กฐ๊ฑด์ ์ถ๊ฐํด์ ์ฝ๊ฐ์ ์ต์ ํ ๋ ๋ฒ์ .
์ ํ ์ ๋ ฌ Selection Sort
void selectionSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int min_idx = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
}
int temp = arr[i];
arr[i] = arr[min_idx];
arr[min_idx] = temp;
}
}
๋ฒ๋ธ์ ๋ ฌ๊ณผ ๋ฌ๋ฆฌ ์กฐ๊ธฐ ์ข ๋ฃ ์กฐ๊ฑด์ ์ถ๊ฐํ ์ ์๋ค.
์์ ์ธ ๋ด์ฉ
์์ ์์๋ ๋ค๋ฃจ์ง ์์์ง๋ง ๊ถ๊ธํด์ ์๊ฐํด ๋ณธ ๊ฒ๋ค์ด๋ค.
๋ฒ๋ธ ์ ๋ ฌ๊ณผ์ ๋น๊ต
์กฐ๊ธฐ ์ข ๋ฃ ๊ฐ๋ฅ์ฑ์ ์ฐจ์ด
๋ฒ๋ธ ์ ๋ ฌ์์ ์กฐ๊ธฐ ์ข
๋ฃ๊ฐ ๊ฐ๋ฅํ ์ด์ :
๋ฒ๋ธ ์ ๋ ฌ์ ์ธ์ ํ ์์๋ค๋ผ๋ฆฌ ๋น๊ตํ์ฌ ์๋ฆฌ๋ฅผ ๋ฐ๊พธ๋ ๋ฐฉ์์ผ๋ก ์งํ๋๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค. i ์ํ๋ง๋ค j ์ํ๋ฅผ ๋ฐ๋ณตํ๋ ๊ฒ์ ์ ํ ์ ๋ ฌ๊ณผ ๋์ผํ์ง๋ง, ๋ฒ๋ธ ์ ๋ ฌ์์๋ j ์ํ ๋์ ์ฌ๋ฌ ๋ฒ์ ์ธ์ ํ ๋ ์์ ๊ตํ์ด ์ด๋ฃจ์ด์ง๋ค.
ํต์ฌ์ j ์ํ ๋ ํ ๋ฒ๋ ๊ตํ์ด ์ด๋ฃจ์ด์ง์ง ์์๋ค๋ ๊ฒ์ด ์ด๋ฏธ ํด๋น ๋ฐฐ์ด์ด ์ ๋ ฌ๋์์์ ์๋ฏธํ๋ค๋ ์ ์ด๋ค. ์ด ์กฐ๊ฑด์ ํด๋นํ๋ ๋ถ๋ฆฐ ๋ณ์๋ฅผ ์ ์ธํ์ฌ ์ฌ์ฉํ๋ค๋ฉด, ๋ฐ๋ณต๋ฌธ์ ์กฐ๊ฑด์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์กฐ๊ธฐ ์ข
๋ฃ๋ฅผ ๊ตฌํํ ์ ์๋ค.
์ ํ ์ ๋ ฌ์์ ์กฐ๊ธฐ ์ข
๋ฃ๊ฐ ์ด๋ ค์ด ์ด์ :
์ ํ ์ ๋ ฌ์ ๊ฐ ์ํ์์ ์ต์๊ฐ์ ์ฐพ์ ํ ๋จ ํ ๋ฒ๋ง ๊ตํํ๋ค. ํ์ฌ ์์น์ ์ฌ๋ฐ๋ฅธ ๊ฐ์ด ์ด๋ฏธ ์์ด๋ ์ ์ฒด ๋ฐฐ์ด์ ์ค์บํด์ผ๋ง ๊ทธ๊ฒ์ด ์ต์๊ฐ์์ ํ์ธํ ์ ์๋ค.
์ฑ๋ฅ ๋น๊ต
๊ทธ๋ ๋ค๋ฉด ๋ฒ๋ธ ์ ๋ ฌ์ด ์ ํ ์ ๋ ฌ๋ณด๋ค ๋ฌด์กฐ๊ฑด ์ฐ์ํ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ผ๊น? ๊ทธ๋ ์ง ์๋ค. ๋ฒ๋ธ ์ ๋ ฌ์์๋ ์ฆ์ ๊ตํ ์ฐ์ฐ์ด ์ด๋ฃจ์ด์ง๊ธฐ ๋๋ฌธ์ด๋ค.
๊ตํ ํ์ ์ฐจ์ด:
- ์ ํ ์ ๋ ฌ: O(n) - ๊ฐ ์ํ๋ง๋ค ์ต๋ 1๋ฒ์ ๊ตํ
- ๋ฒ๋ธ ์ ๋ ฌ: O(nยฒ) - ์ธ์ ์์๋ค์ ๋น๋ฒํ ๊ตํ
๊ตํ ์ฐ์ฐ์ ๋น๊ต ์ฐ์ฐ๋ณด๋ค ๋น์ฉ์ด ํฌ๋ฏ๋ก, ์ ์ ๊ตํ ํ์๋ฅผ ๊ฐ์ง ์ ํ ์ ๋ ฌ์ด ์ผ๋ฐ์ ์ผ๋ก ๋ ํจ์จ์ ์ด๋ค.
์กฐ๊ธฐ ์ข ๋ฃ ์กฐ๊ฑด์ ์๊ฐํด๋ณผ ์ ์์๊น?
function selectionSort(arr) {
for (let i = 0; i < arr.length; i++) {
let min_idx = i;
let check = true;
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
if(arr[j]>arr[j+1]){
check = false;
}
}
if(min_idx === i && check){
break;
}else{
let temp = arr[i];
arr[i] = arr[min_idx];
arr[min_idx] = temp;
}
}
}
๋์ ์์
[5, 3, 1, 7, 9]
๋ฐฐ์ด ์ ๋ ฌ:
- ์ฒซ ๋ฒ์งธ ์ํ: 1์ ์ฐพ์์ ๋งจ ์์ผ๋ก โ
[1, 3, 5, 7, 9]
- ๋ ๋ฒ์งธ ์ํ: 3์ด ์ด๋ฏธ ์ต์๊ฐ์ด๊ณ , ๋๋จธ์ง๊ฐ ์ ๋ ฌ๋จ์ ํ์ธ โ ์กฐ๊ธฐ ์ข ๋ฃ
ํ๊ณ์
์ถ๊ฐ ๋น๊ต ์ฐ์ฐ์ ์ค๋ฒํค๋:
- ๊ธฐ์กด ์ ํ ์ ๋ ฌ: ์ต์๊ฐ ์ฐพ๊ธฐ ์ฐ์ฐ๋ง ์ํ
- ๊ฐ์ ๋ ๋ฒ์ : ์ต์๊ฐ ์ฐพ๊ธฐ + ์ ๋ ฌ ์ํ ํ์ธ ์ฐ์ฐ
- ์ต์ ์ ๊ฒฝ์ฐ: ๋น๊ต ์ฐ์ฐ์ด ์ฝ 2๋ฐฐ๋ก ์ฆ๊ฐ
์ต์ ์ ๊ฒฝ์ฐ๋ค:
- ์ญ์์ผ๋ก ์ ๋ ฌ๋ ๋ฐฐ์ด:
[9, 7, 5, 3, 1]
- ๋งค๋ฒ ๊ตํ์ด ํ์ํ๊ณ , ์ ๋ ฌ ์ํ ํ์ธ๋ ํญ์ ์คํจ
- ๊ฑฐ์ ์ญ์์ธ ๋ฐฐ์ด:
[8, 7, 6, 5, 1, 2, 3, 4]
- ์ค๊ฐ๊น์ง ์ ๋ ฌ ํ์ธ์ด ๊ณ์ ์คํจ
- ๋ฌด์์ ๋ฐฐ์ด: ์ ๋ ฌ ์ํ๊ฐ ํ๋ฐ๋ถ์์์ผ ๋ฌ์ฑ๋๋ ๊ฒฝ์ฐ
๊ฒฐ๋ก
์ ํ ์ ๋ ฌ์ ์กฐ๊ธฐ ์ข ๋ฃ ์ต์ ํ๋ ์ด๋ฏธ ์ ๋ ฌ๋ ๋ฐ์ดํฐ๋ ๋ถ๋ถ์ ์ผ๋ก ์ ๋ ฌ๋ ๋ฐ์ดํฐ์์๋ง ํจ๊ณผ์ ์ด๋ค. ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ์๋ ์ถ๊ฐ ๋น๊ต ์ฐ์ฐ์ผ๋ก ์ธํ ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ ์ ์์ด, ์ค์ฉ์ฑ์ ์ ํ์ .
์ฝ์ ์ ๋ ฌ Insertion Sort
void insertionSort(int arr[], int n) {
for (int i = 1; i < n; ++i) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
์ฅ์ :
- ๊ฐ๋จํ ๊ตฌํ
- ์์ ๋ฐ์ดํฐ์ ํจ์จ์
- ์ ์์ : ์ ๋ ฅ ๋ฆฌ์คํธ๊ฐ ์ด๋น ์ ๋ ฌ๋์ด์๋ค๋ฉด, ์ฝ์ ์ ๋ ฌ์ d๊ฐ ๋ฐ๋ฒ์ ํ์์ผ ๋ O(n+d)์ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค.
- ์จ๋ผ์ธ : ์ฝ์ ์ ๋ ฌ์ ์ ๋ ฅ ๋ฆฌ์คํธ๋ฅผ ๋ฐ์ผ๋ฉด์ ์ ๋ ฌํ ์ ์๋ค.
๋ณํฉ ์ ๋ ฌ Merge Sort
Divide-and-Conquere์ ๋ํ์ ์ธ ์์.
#include <stdio.h>
#include <stdlib.h>
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int arr[], int l, int m, int r){
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
// Create temp arrays
int L[n1], R[n2];
// Copy data to temp arrays L[] and R[]
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
// Merge the temp arrays back into arr[l..r
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = R[j];
j++;
}
k++;
}
// Copy the remaining elements of L[],
// if there are any
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
// Copy the remaining elements of R[],
// if there are any
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
// l is for left index and r is right index of the
// sub-array of arr to be sorted
void mergeSort(int arr[], int l, int r){
if (l < r) {
int m = l + (r - l) / 2;
// Sort first and second halves
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}
// Driver code
int main(){
int arr[] = {38, 27, 43, 10};
int arr_size = sizeof(arr) / sizeof(arr[0]);
mergeSort(arr, 0, arr_size - 1);
int i;
for (i = 0; i < arr_size; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
ํ ์ ๋ ฌ Heap Sort
// To heapify a subtree rooted with node i
// which is an index in arr[].
void heapify(int arr[], int n, int i) {
// Initialize largest as root
int largest = i;
// left index = 2*i + 1
int l = 2 * i + 1;
// right index = 2*i + 2
int r = 2 * i + 2;
// If left child is larger than root
if (l < n && arr[l] > arr[largest]) {
largest = l;
}
// If right child is larger than largest so far
if (r < n && arr[r] > arr[largest]) {
largest = r;
}
// If largest is not root
if (largest != i) {
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
// Main function to do heap sort
void heapSort(int arr[], int n) {
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// One by one extract an element from heap
for (int i = n - 1; i > 0; i--) {
// Move current root to end
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// Call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
// A utility function to print array of size n
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// Driver's code
int main() {
int arr[] = {9, 4, 3, 8, 10, 2, 5};
int n = sizeof(arr) / sizeof(arr[0]);
heapSort(arr, n);
printf("Sorted array is \n");
printArray(arr, n);
return 0;
}
๊ธฐ๋ณธ ๊ฐ๋
ํ ์ ๋ ฌ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐฐ์ด์ ํ์ผ๋ก ๋ง๋ค๊ณ , ๊ฑฐ๊ธฐ์ ๋ค์ ์ ๋ ฌ์ ์ํํ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
ํ ์ ํ ๊ธฐ์ค
- ์ค๋ฆ์ฐจ์ ์ ๋ ฌ: max heap ์ฌ์ฉ
- ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ: min heap ์ฌ์ฉ
์ด๋ ๊ฒ ํ๋ ์ด์ ๋ ๋ฃจํธ ๋ ธ๋(์ต๋๊ฐ ๋๋ ์ต์๊ฐ)๋ฅผ ์ถ์ถํ์ฌ ๋ฐฐ์ด์ ๋งจ ๋ค๋ถํฐ ์ฐจ๋ก๋๋ก ๋ฐฐ์นํ๊ธฐ ๋๋ฌธ์ด๋ค.
์๊ฐ ๋ณต์ก๋
์ ์ฒด ์๊ฐ ๋ณต์ก๋: O(n log n)
์๊ณ ๋ฆฌ์ฆ ๊ตฌ์ฑ
heapSort()
ํจ์๋ ๋ ๊ฐ์ ์ฃผ์ ๊ณผ์ ์ผ๋ก ๋๋๋ค:
1๋จ๊ณ: ํ ๊ตฌ์ฑ (Build Heap)
- ๊ณผ์ : ๋ฌด์์ ๋ฐฐ์ด์ max heap์ผ๋ก ๋ณํ
- ์๊ฐ ๋ณต์ก๋: O(n)
- ์ค๋ช : ๋ฐฐ์ด์ ์ํ์ ๋ฐ๋ผ ๋ค๋ฅด์ง๋ง, ์ต์ ์ ๊ฒฝ์ฐ์๋ ๊ฑฐ์ n์ ๊ทผ์ ํ๋ ํ์์ ์ฐ์ฐ์ด ์ด๋ฃจ์ด์ง๋ค.
2๋จ๊ณ: ์ ๋ ฌ ์ํ (Sorting)
- ๊ณผ์ : ํ์์ ์ฐจ๋ก๋๋ก ์ต๋๊ฐ์ ์ถ์ถํ์ฌ ์ ๋ ฌ
- ์๊ฐ ๋ณต์ก๋: O(n log n)
- ์ค๋ช
:
- ๊ฐ ๋ ธ๋ n๊ฐ์ ๋ํด heapify ์ฐ์ฐ์ ์ํ
- heapify ์์ฒด๋ O(log n)์ ์๊ฐ์ด ๊ฑธ๋ฆผ
- ์ด๋ฅผ n๋ฒ ๋ฐ๋ณตํ๋ฏ๋ก O(n log n)
์ ์ฒด ์๊ฐ ๋ณต์ก๋ ๊ณ์ฐ
O(n) + O(n log n) = O(n log n)
ํ ๊ตฌ์ฑ ๋จ๊ณ์ O(n)์ ์ ๋ ฌ ๋จ๊ณ์ O(n log n)์ ํก์๋์ด ์ ์ฒด์ ์ผ๋ก O(n log n) ์ด ๋๋ค.
ํต์ฌ ํฌ์ธํธ
- ์์ ์ ์ธ ์ฑ๋ฅ: ์ต์ , ํ๊ท , ์ต์ ์ ๊ฒฝ์ฐ ๋ชจ๋ O(n log n)
- ์ ์๋ฆฌ ์ ๋ ฌ: ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ด ๊ฑฐ์ ํ์ํ์ง ์์ (O(1))
- ๋น์์ ์ ๋ ฌ: ๋์ผํ ๊ฐ์ ๊ฐ์ง ์์๋ค์ ์๋์ ์์๊ฐ ๋ณด์ฅ๋์ง ์์
ํต ์ ๋ ฌ Quick Sort
๋ณํฉ์ ๋ ฌ๊ณผ ๋น์ทํ๋ค, ํต ์ ๋ ฌ๋ Divide-Conquer ์๊ณ ๋ฆฌ์ฆ์ ์์.
Divide : ๋ฐฐ์ด์ ํน์ ์ธ๋ฑ์ค q๋ฅผ ๊ธฐ์ค์ผ๋ก [low ... q-1]
๊ณผ [q+1 ... high]
๋ก ๋๋๋ค.
Conquer : ์์ ๋ ๋ถ์ ๋ฐฐ์ด๋ค์์ ๋ค์ ํต ์ ๋ ฌ์ ์ฌ๊ท ํธ์ถ
- ๋ฐฐ์ด ์์ ํญ๋ชฉ์ด 1๊ฐ ์ดํ๋ผ๋ฉด ๋ฐํํ๋ค.
- ๋ฐฐ์ด ์์ ํ ํญ๋ชฉ์ Pivot์ผ๋ก ์ ํํ๋ค. (๋ณดํต ๋ฐฐ์ด์ ์ ์ผ ์ผ์ชฝ/์ค๋ฅธ์ชฝ ํญ๋ชฉ)
- ๋ฐฐ์ด์ pivot๋ณด๋ค ์์ ํญ๋ชฉ๋ค๊ณผ ํฐ ํญ๋ชฉ์ธ ๋ ๋ถ๋ถ์ผ๋ก ์ ๋ฆฌํด์ ๋๋๋ค.
- ์๋ณธ ๋ฐฐ์ด์ ๋ ๋ฐ์ชฝ์ ๋ํด ์๊ณ ๋ฆฌ์ฆ์ ์ฌ๊ท์ ์ผ๋ก ๋ฐ๋ณตํ๋ค.
// partition function
int partition(int arr[], int low, int high) {
// Choose the pivot
int pivot = arr[high];
// Index of smaller element and indicates
// the right position of pivot found so far
int i = low - 1;
// Traverse arr[low..high] and move all smaller
// elements to the left side. Elements from low to
// i are smaller after every iteration
for (int j = low; j <= high - 1; j++) {
if (arr[j] < pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}
// Move pivot after smaller elements and
// return its position
swap(&arr[i + 1], &arr[high]);
return i + 1;
}
// The QuickSort function implementation
void quickSort(int arr[], int low, int high) {
if (low < high) {
// pi is the partition return index of pivot
int pi = partition(arr, low, high);
// recursion calls for smaller elements
// and greater or equals elements
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
void swap(int* a, int* b) {
int t = *a;
*a = *b;
*b = t;
}
ํต ์ ๋ ฌ์ ๋ฌธ์ ๋ ๊ณ์ํด์ ํผ๋ฒ์ ์ต๋๊ฐ ํน์ ์ต์๊ฐ์ผ๋ก ์ก์์ ๋ ๊ฐ์ ๋ถ๋ถ ๋ฐฐ์ด๋ก ๋๋์ด์ง์ง ์๊ฒ ๋๋ ์ํฉ์ด ๋ฐ์ํ๋ฉด ์๊ฐ ๋ณต์ก๋๊ฐ ๋ผ๋ ๊ฒ.