说明
采用分治思想
, 先进行序列划分,再进行元素的有序合并
时间空间复杂度
排序算法 | 平均时间复杂度 | 最好时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
归并排序 | O() | O() | O() | O(n) | 稳定 |
代码
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
// 归并过程函数
void Merge(int arr[], int l, int m, int r) {
// 开辟额外的空间,将两个小段有序的序列合并成大段有序的序列
int* p = new int[r - l + 1];
int idx = 0; // 数组的下标
int i = l; // 左边序列的首元素
int j = m + 1; // 右边元素的首元素
while (i <= m && j <= r) {
if (arr[i] <= arr[j]) {
p[idx++] = arr[i++];
} else {
p[idx++] = arr[j++];
}
}
// 左边的小段还有剩余
while (i <= m) {
p[idx++] = arr[i++];
}
// 右边的小段还有剩余
while (j <= r) {
p[idx++] = arr[j++];
}
// 再把合并好的大段有序的结果拷贝到原始arr数组的[l, r]区间内
for (i = l, j = 0; i <= r; i++, j++) {
arr[i] = p[j];
}
// 释放内存
delete []p;
}
// 归并排序递归接口
void MergeSort(int arr[], int begin, int end) {
// 递归结束的条件
if (begin >= end) {
return;
}
int mid = (begin + end) / 2;
// 先递
MergeSort(arr, begin, mid);
MergeSort(arr, mid + 1, end);
// 再归并. [begin, mid], [mid + 1, end]将两个小段有序的序列合并成大段有序的序列
Merge(arr, begin, mid, end);
}
void MergeSort(int arr[], int size) {
MergeSort(arr, 0, size - 1);
}
int main() {
int arr[10];
srand(time(nullptr));
for (int i = 0; i < 10; i++) {
arr[i] = rand() % 100 + 1;
}
for (int v : arr) {
cout << v << " ";
}
cout << endl;
MergeSort(arr, 10);
for (int v : arr) {
cout << v << " ";
}
cout << endl;
return 0;
}
测试
➜ build git:(main) ✗ ./MergeSort
65 70 37 37 19 23 70 86 89 45
19 23 37 37 45 65 70 70 86 89