分而治之的分治思想
分治思想
- 分(Devide):递归地将问题分解为多个形式与原问题一致,规模更小的子问题。
- 治(Conquer): 求解子问题。(如果存在重叠的子问题, 则可以考虑用记忆搜索或动态规划进行优化)
- 合并(Combine): 将子问题的解合并为原问题的解。

归并排序(Merge Sort)
void MergeSort(int* nums, int left, int right)
: 对 nums 数组 [left, right)
区间的元素进行排序。
- 分(Devide):令
mid = (left + right) / 2
, 将区间划分为 [left, mid)
和 [mid, right)
两个区间。 - 治(Conquer): 分别对
[left, mid)
和 [mid, right)
两个区间的元素进行排序。
MergeSort(nums, left, mid);
MergeSort(nums, mid, right);
- 合并(Combine): 将
[left, mid)
和 [mid, right)
两个区间排好序的元素进行合并。
while (i < mid && j < right) {
if (nums[i] <= nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
while (i < mid) {
temp[k++] = nums[i++];
}
while (j < right) {
temp[k++] = nums[j++];
}
for (i = left; i < right; ++i) {
nums[i] = temp[i-left];
}
- 完整的实现源码如下:
#include <iostream>
using namespace std;
const static int NUMS_MAX_LEN = 1024;
void Print(int* nums, int len) {
for (int i = 0; i < len; i++) {
cout << nums[i] << " ";
}
cout << endl;
}
void MergeSort(int* nums, int left, int right) {
if (right <= left + 1) {
return;
}
int mid = (left + right) / 2;
MergeSort(nums, left, mid);
MergeSort(nums, mid, right);
int* temp = new int[right-left];
int i = left, j = mid, k = 0;
while (i < mid && j < right) {
if (nums[i] <= nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
while (i < mid) {
temp[k++] = nums[i++];
}
while (j < right) {
temp[k++] = nums[j++];
}
for (i = left; i < right; ++i) {
nums[i] = temp[i-left];
}
delete[] temp;
}
int main() {
int n, nums[NUMS_MAX_LEN];
while (cin >> n) {
for (int i = 0; i < n && i < NUMS_MAX_LEN; i++) {
cin >> nums[i];
}
MergeSort(nums, 0, n);
Print(nums, n);
}
return 0;
}