합병 정렬(Merge Sort)이란?
- 작은 조각까지 나눠, 조각을 병합하면서 정렬하는 방식이다.
- 일반적인 방법으로 구현했을 때 이 정렬은 안정 정렬에 속한다.
- 분할 정복 알고리즘의 하나이다.
작동 방식

1) 리스트를 절반으로 계속해서 나눈다. (분할)
2) 가장 작은 단위로 나눠지면, 나눠진 두 조각의 값들을 비교한다.
3) 두 리스트를 비교하면서 하나의 정렬된 리스트에 값을 정렬한다. (합병)
소스코드
#include <iostream>
using namespace std;
int* sorted;
void mergeSort(int* arr, int left, int right);
void merge(int* arr, int left, int right);
int main() {
int N;
cin >> N;
sorted = new int[N];
int* arr = new int[N];
for (int i = 0; i < N; i++) {
cin >> arr[i];
}
mergeSort(arr, 0, N - 1);
for (int i = 0; i < N; i++) {
cout << arr[i] << endl;
}
delete[] arr;
delete[] sorted;
return 0;
}
void mergeSort(int* arr, int left, int right) {
int mid;
if (left < right) {
mid = (left + right) / 2;
// 분할
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// 합병
merge(arr, left, right);
}
}
void merge(int* arr, int left, int right) {
int mid = (left + right) / 2;
int l = left;
int r = mid + 1;
int i = left;
while (l <= mid && r <= right) {
if (arr[l] < arr[r]) {
sorted[i++] = arr[l++];
}
else {
sorted[i++] = arr[r++];
}
}
// 남은 수들
if (l <= mid) {
for (l; l <= mid; l++) {
sorted[i++] = arr[l];
}
}
else {
for (r; r <= right; r++) {
sorted[i++] = arr[r];
}
}
// arr배열에 값 복사
for (int j = left; j <= right; j++) {
arr[j] = sorted[j];
}
}
소스코드 이해
합병정렬은 보통 재귀로 구현한다.
합병정렬이라고 검색하면 흔히 나오는 그림들을 보며 작동 방식을 이해하는 데는 큰 어려움이 없었다.
하지만 막상 구현하려고 하니 어떻게 작성해야 할 지 막막해 흐름을 그림으로 그려보았다.
아래는 소스코드 진행 흐름 그대로 작동 방식을 표현한 그림이다. (일부)

① ~ ④ 배열의 왼쪽부분 부터 길이가 1일 때까지(left == right) 쪼갠다.
⑤ 배열의 왼쪽, 오른쪽 부분 값을 비교하여, 작은 값부터 sorted 배열에 저장한다.
정렬된 부분을 다시 비교해야 하므로, 정렬된 부분을 arr배열에 copy한다.
⑦ ①에서 나눈 왼쪽부분을 분할 및 정렬했으므로, 오른쪽 부분을 분할한다.
⑧ 배열의 왼쪽, 오른쪽 부분 값을 비교하여, 작은 값부터 sorted 배열에 저장한다.
정렬된 부분을 다시 비교해야 하므로, 정렬된 부분을 arr배열에 copy한다.
시간복잡도
평균의 경우 : O(nlogn)
최선의 경우 : O(nlogn)
최악의 경우 : O(nlogn)
배열을 길이가 1일 때 까지 계속 절반으로 쪼개면, 그 깊이는 logn이 된다.

나눌 수록 배열의 개수는 많아지지만, 데이터는 n개로 모두 동일하다.
따라서 각 깊이별로 수행되는 연산의 시간복잡도는 O(n)이다.
이를 종합하면 시간복잡도는 O(nlogn)이 된다.
'Algorithm > 개념' 카테고리의 다른 글
| [Algorithm] 정렬 - 힙 정렬 (Heap Sort) (0) | 2019.05.29 |
|---|---|
| [Algorithm] 정렬 - 빠른 정렬 (Quick Sort) (0) | 2019.05.26 |
| [Algorithm] 정렬 - 선택 정렬 (Selection Sort) (0) | 2019.05.23 |
| [Algorithm] 정렬 - 거품 정렬 (Bubble Sort) (0) | 2019.05.23 |
| [Algorithm] 정렬 - 삽입 정렬 (Insertion Sort) (0) | 2019.05.23 |