정렬(Sorting)은 특정 기준에 따라 데이터의 순서를 재배열하는 과정입니다.
정렬은 다양한 알고리즘에서 핵심 전처리 단계로 활용됩니다.
예시: 숫자를 오름차순으로 정렬하면…
이진 탐색을 사용해 시간에 원하는 값을 빠르게 찾을 수 있습니다.🔍
정렬 알고리즘은 주로 비교(Comparisons)와 교환(Exchanges) 횟수로 복잡도를 분석합니다.
개념: 인접한 두 요소를 비교하고, 큰 값을 뒤로 보낸다.
동작:
복잡도: 비교 횟수 =
for (int pass = 0; pass < n-1; pass++) {
for (int i = 0; i < n-1-pass; i++) {
if (A[i] > A[i+1]) swap(A[i], A[i+1]);
}
}
개념:
- bubble sort보다 교환을 덜 하는 방식
- 매 Pass마다 가장 작은(또는 큰) 요소를 선택해 제자리에 둠.
동작:
minIdx
) 찾기minIdx
와 현재 기준 위치 i
를 교환복잡도: 비교, 교환
for (int i = 0; i < n-1; i++) {
int minIdx = i;
for (int j = i+1; j < n; j++) if (A[j] < A[minIdx]) minIdx = j;
swap(A[i], A[minIdx]);
}
개념:
동작:
복잡도: 평균/최악 , 최선
for (int i = 1; i < n; i++) {
int tmp = v[i];
int j = i;
// 나보다 작은 애 만날 때까지 앞으로 전진
while (j >= 1 && v[j-1] > tmp) {
swap(v[j], v[j - 1]);
j--;
}
}
개념:
동작:
복잡도: Gap 시퀀스에 따라 다르나, 일반적으로
void shellsort(vector<int>& A) {
int n = A.size();
// gap 시퀀스
for (int gap = n/2; gap > 0; gap /= 2) {
// 각 시퀀스의 두 번째 요소부터 끝까지 돌기
for (int i = gap; i < n; i++) {
int temp = A[i];
int j = i;
// 나보다 작은 애 만날 때까지 앞으로 전진
while (j >= gap && A[j - gap] > temp) {
swap(A[j], A[j - gap]);
j -= gap;
}
}
}
}
개념: 분할 정복(Divide & Conquer)
동작:
병합(Merge):
다음 두 정렬된 서브리스트를 병합한다고 해봅시다.
병합 과정은 다음과 같이 진행됩니다.
단계 | 비교 대상 | 작은 값 선택 | tmp 배열 상태 | L 포인터(i) | R 포인터(j) |
---|---|---|---|---|---|
1 | vs | 1 (R[j]) | [1] | i=0 | j=1 |
2 | vs | 2 (L[i]) | [1, 2] | i=1 | j=1 |
3 | vs | 3 (R[j]) | [1, 2, 3] | i=1 | j=2 |
4 | vs | 5 (L[i]) | [1, 2, 3, 5] | i=2 | j=2 |
5 | vs | 7 (L[i]) | [1, 2, 3, 5, 7] | i=3 | j=2 |
6 | vs | 8 (R[j]) | [1, 2, 3, 5, 7, 8] | i=3 | j=3 (끝) |
--- | R 소진 | — | [1, 2, 3, 5, 7, 8] | i=3 | j=3 |
7 | 남은 L 붙이기 | 9 (L[i]) | [1, 2, 3, 5, 7, 8, 9] | i=4 (끝) | j=3 |
최종 병합 결과:
[1, 2, 3, 5, 7, 8, 9]
복잡도: 깊이 log n × 각 레벨 O(n) =
void merge_sort(vector<int>& A, int l, int r) {
if (l >= r) return;
int m = (l + r) / 2;
merge_sort(A, l, m);
merge_sort(A, m+1, r);
// 병합
vector<int> tmp;
int i = l, j = m+1;
while (i <= m && j <= r) {
if (A[i] <= A[j]) tmp.push_back(A[i++]);
else tmp.push_back(A[j++]);
}
// 남은 원소 처리
while (i <= m) tmp.push_back(A[i++]);
while (j <= r) tmp.push_back(A[j++]);
// 다시 원본 배열에 복사
for (int k = l; k <= r; k++) A[k] = tmp[k-l];
}
더 빠른 정렬(Quick Sort, Heap Sort 등)은 다음 시간에 계속... 🚀