Ý tưởng: Chia mảng thành 2 nửa, đệ quy sắp xếp từng nửa, rồi trộn (merge) 2 nửa đã sắp xếp lại thành một mảng hoàn chỉnh.
#include <bits/stdc++.h>
using namespace std;
void merge(vector<int>& a, int lo, int mid, int hi) {
vector<int> temp;
int i = lo, j = mid + 1;
// Trộn 2 nửa đã sắp xếp
while (i <= mid && j <= hi) {
if (a[i] <= a[j]) // <= để đảm bảo STABLE
temp.push_back(a[i++]);
else
temp.push_back(a[j++]);
}
while (i <= mid) temp.push_back(a[i++]);
while (j <= hi) temp.push_back(a[j++]);
// Copy lại vào mảng gốc
for (int k = lo; k <= hi; k++)
a[k] = temp[k - lo];
}
void mergeSort(vector<int>& a, int lo, int hi) {
if (lo < hi) {
int mid = lo + (hi - lo) / 2;
mergeSort(a, lo, mid); // Sắp nửa trái
mergeSort(a, mid + 1, hi); // Sắp nửa phải
merge(a, lo, mid, hi); // Trộn lại
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
mergeSort(a, 0, n - 1);
for (int x : a) cout << x << " ";
return 0;
}
💡 Merge Sort = "Vua" của Stable Sort
Luôn O(n log n) trong mọi trường hợp. Nhược điểm duy nhất: cần O(n) bộ nhớ phụ (mảng temp). Nhưng trên Linked List → O(1) bộ nhớ phụ!