개념:
동작:
복잡도:
void QuickSort(vector<int>& v, int l, int r) {
if (l >= r) return;
// 왼쪽으로 가면서 pivot보다 큰 아이템을 찾는다
int pivot = v[l];
int left_mark = l + 1;
int right_mark = r;
while (1) {
while (left_mark <= right_mark && pivot >= v[left_mark]) left_mark++;
while (right_mark >= left_mark && pivot <= v[right_mark]) right_mark--;
if (left_mark > right_mark) break;
swap(v[left_mark], v[right_mark]);
}
// pivot과 right mark를 교환
swap(v[l], v[right_mark]);
// divide
QuickSort(v, l, right_mark - 1);
QuickSort(v, right_mark + 1, r);
}
개념:
동작:
시간복잡도 :
void heapSort(vector<int>& arr) {
int n = arr.size();
// Build max-heap : 마지막 부모 노드(n/2-1)부터 루트(0)까지
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// 정렬
for (int end = n - 1; end > 0; end--) {
swap(arr[end], arr[0]);
heapify(arr, end, 0);
}
}
// arr[0..n-1] 구간에서, 루트 i를 최대 힙 속성으로 재조정
void heapify(vector<int>& arr, int n, int i) {
int largest = i;
int left = 2 * i + 1; // 왼쪽 자식
int right = 2 * i + 2; // 오른쪽 자식
if (left < n && arr[left] > arr[largest]) {
largest = left;
}
if (right < n && arr[right] > arr[largest]) {
largest = right;
}
if (largest != i) {
swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
개념:
동작:
시간 복잡도:
void binSort(float arr[], int n) {
vector<vector<float>> b(n);
for (int i = 0; i < n; i++) {
int bi = n * arr[i]; // index in bin
b[bi].push_back(arr[i]);
}
for (int i = 0; i < n; i++) {
sort(b[i]);
}
int index = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < b[i].size(); j++) {
arr[index++] = b[i][j];
}
}
}
개념:
동작 (index array method):
d
를 구함exp=1
부터 시작해서 exp*=10
씩 증가시켜 가면서, 모든 값의 (value/exp)%10
자리수를 기준으로 안정 정렬exp
가 이상이 될 때까지 2 반복시간복잡도:
void radixSort(vector<int>& arr) {
int mx = arr[0];
// 1) 최댓값 찾기
for (int& v : arr) {
if (v > mx) mx = v;
}
// 2) exp = 1, 10, 100 , ... 처리 == 첫 번째 자리 -> 마지막 자리
for (int exp = 1; mx / exp > 0; exp*=10) {
countSortByDigit(arr, exp);
}
}
void countSortByDigit(vector<int>& arr, int exp) {
int n = arr.size();
vector<int> output(n);
int count[10] = { 0, };
// 1) 해당 자리수별 빈도 계산
for (int i = 0; i < n; i++) {
int digit = (arr[i] / exp) % 10;
count[digit]++;
}
// 2) 누적합으로 위치 계산
count[0] = -1; // for 0-based index
for (int i = 1; i < 10; i++) {
count[i] += count[i - 1];
}
// 3) 뒤에서부터 위치 찾기
for (int i = n - 1; i >= 0; i--) {
int digit = (arr[i] / exp) % 10;
output[count[digit]] = arr[i];
count[digit]--;
}
// 4) 원래 배열에 복사
for (int i = 0; i < n; i++) {
arr[i] = output[i];
}
}
Sorting method | algorithm | complexity | stability |
---|---|---|---|
Bubble Sort | Exchanging two neighbor items | stable | |
Selection Sort | Finding the maximum of the remained items | stable | |
Insertion Sort | Keeping the previous list sorted | stable | |
Shell Sort | Sorting sub-lists by gab | ~ | stable |
Merge Sort | Splitting list and merging sub-lists recursively (additional memory) | stable | |
Quick Sort | Splitting list according to pivot value and swapping recursively | Avg.: Worst case: | unstable |
Heap Sort | Utilizing max-heap (additional memory | unstable | |
Bin (bucket) Sort | Hashing by MSB and sorting each bin (additional memory) | stable | |
Radix Sort | Hashing from LSB to MSB (additional memory) | stable |