📕 マージソート.
📌マージソートの特徴.
- 指定要素を部分配列に分解してソート.
- 最後にソート済み配列をマージするので計算量O(nlogn).
📌マージソートの手順.
1️⃣配列全体を対象としてmergeSortを行う.
2️⃣mergeSortは以下のとおり.
-- 1️⃣指定のn個の要素を含む部分配列をそれぞれn/2個の要素を含む2つの部分配列に分割.
-- 2️⃣その2つの部分配列をそれぞれmergeSortでソート.
-- 3️⃣得られた2つのソート済み部分配列をmergeにより統合.
整列済み配列L={1,5}とR={2,4,8}をマージする場合は以下のとおり.
配列{9,6,7,2,5,1,8,4,2}に対してマージソート行う場合は以下のとおり.
指定要素をn/2に分割していく.
// マージソート
void mergeSort(int A[], int n, int left, int right) {
if (left+1 < right) {
int mid = (left + right) / 2;
mergeSort(A, n, left, mid);
mergeSort(A, n, mid, right);
merge(A, n, left, mid, right);
}
}
得られた2つのソート済み部分配列をマージ.
#include <iostream>
using namespace std;
#define MAX 500000
#define SENTINEL 200000000
int L[MAX/2+2], R[MAX/2+2];
int cnt;
void merge(int A[], int n, int left, int mid, int right) {
// 部分配列に入れ替え
int n1 = mid - left;
for (int i = 0; i < n1; i++) {
L[i] = A[left + i];
}
int n2 = right - mid;
for (int i = 0; i < n2; i++) {
R[i] = A[mid + i];
}
// 番兵の設定
L[n1] = R[n2] = SENTINEL;
int i = 0, j = 0;
for (int k = left; k < right; k++) {
cnt++;
// 分割された最小要素同士を比較
if (L[i] <= R[j]) {
A[k] = L[i++];
} else {
A[k] = R[j++];
}
}
}
🔎対象ソースは以下に格納.
/source/5.hsort/merge.cpp