#include <iostream>
#include <vector>
using namespace std;
// 두 개의 정렬된 배열을 병합하는 함수
void merge(vector<int>& arr, int left, int mid, int right)
{
vector<int> temp;
int i = left, j = mid + 1;
// 두 개의 부분 배열을 합친다.
while (i <= mid && j <= right)
{
if (arr[i] < arr[j]) temp.push_back(arr[i++]);
else temp.push_back(arr[j++]);
}
while (i <= mid) temp.push_back(arr[i++]);
while (j <= right) temp.push_back(arr[j++]);
// 원래 배열에 정렬된 값 반영
for (int k = left; k <= right; k++) arr[k] = temp[k - left];
}
// 분할 정복을 이용한 합병 정렬
void mergeSort(vector<int>& arr, int left, int right)
{
if (left >= right) return;
int mid = (left + right) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
int main()
{
vector<int> arr = { 38, 27, 43, 3, 9, 82, 10 };
mergeSort(arr, 0, arr.size() - 1);
for (int num : arr) cout << num << " ";
return 0;
}
✅ 합병 정렬은 "분할 정복(Divide and Conquer)"을 활용한 정렬 알고리즘
✅ O(N log N) 시간 복잡도
✅ 큰 문제(배열 정렬)를 작은 문제(부분 배열 정렬)로 나눈 뒤 합치는 방식으로 동작
1️⃣ 분할(Divide)
2️⃣ 정복(Conquer)
3️⃣ 합병(Combine)
void mergeSort(vector<int>& arr, int left, int right)
{
if (left >= right) return; // 배열의 크기가 1이면 종료
int mid = (left + right) / 2;
mergeSort(arr, left, mid); // 왼쪽 절반 정렬
mergeSort(arr, mid + 1, right); // 오른쪽 절반 정렬
merge(arr, left, mid, right); // 정렬된 두 개를 합치기
}
📌 Step 1: 처음에는 배열 전체를 반으로 나눕니다.
[38, 27, 43, 3, 9, 82, 10]
|
v
[38, 27, 43, 3] | [9, 82, 10] (배열을 두 개로 분할)
📌 Step 2: 각각 다시 반으로 나눕니다.
[38, 27, 43, 3] → [38, 27] | [43, 3]
[9, 82, 10] → [9, 82] | [10]
📌 Step 3: 더 이상 나눌 수 없을 때까지 계속 나눕니다.
[38, 27] → [38] | [27]
[43, 3] → [43] | [3]
[9, 82] → [9] | [82]
✅ 이제 모든 원소가 한 개짜리 배열이 되었습니다!
📌 Step 4: 이제 정렬된 두 개씩 병합을 시작합니다. 1️⃣ [38]과 [27]을 합쳐 정렬 → [27, 38]
2️⃣ [43]과 [3]을 합쳐 정렬 → [3, 43]
3️⃣ [9]과 [82]을 합쳐 정렬 → [9, 82]
📌 Step 5: 다시 병합하면서 정렬합니다.
[27, 38] + [3, 43] → [3, 27, 38, 43]
[9, 82] + [10] → [9, 10, 82]
📌 Step 6: 마지막 병합 (정렬 완료)
[3, 27, 38, 43] + [9, 10, 82] → [3, 9, 10, 27, 38, 43, 82]
✅ 최종적으로 완전히 정렬된 배열이 됩니다! 🚀
O(N log N)
✅ 일반적인 O(N²) 정렬보다 훨씬 빠름!
단계 설명
1️⃣ 분할 (Divide) | 배열을 반으로 계속 나눔 |
2️⃣ 정복 (Conquer) | 배열 크기가 1이 될 때까지 재귀 호출 |
3️⃣ 합병 (Combine) | 정렬된 두 개의 부분 배열을 하나로 합침 |
분할 정복 : 이진 탐색 (Binary Search) (0) | 2025.03.02 |
---|---|
🚀 std::sort() vs mergeSort() (0) | 2025.03.02 |
트리 순회(Tree Traversal) 방법 02 : 코드 (0) | 2025.03.02 |
🚀 트리 순회(Tree Traversal) 방법 : 후위, 전위, 중위, 레벨 (0) | 2025.03.02 |
🚀 DFS와 BFS의 차이점! (0) | 2025.03.02 |