合并排序使用了“分治法”的策略。
“将原问题划分成n个规模较小而结构与原问题相似的子问题;递归地解决这些子问题;然后合并其结果,就得到原问题的解。”这就是分治策略。
分治策略在每一层递归上有以下三个步骤:
1)分解:将原问题分解成一系列子问题;
2)解决:递归地解各子问题;
3)合并:将子问题的解合并成原问题的解。
合并排序依照上述策略:
1)分解:将n个元素分成两个含n/2个元素的子序列;
2)解决:用合并排序法对两个子序列递归地排序;
3)合并:合并两个已排序的子序列以得到排序结果。
以下代码演示了合并排序算法:
- #include <iostream>
- #include <limits>
-
- using namespace std;
-
-
- void merge(int A[], int p, int q, int r);
-
- void mergeSort(int A[], int p, int r);
-
- int main() {
- int A[10] = {20, 31, 14, 5, 11, 7, 83, 3, 5, 67};
-
- for(int i = 0; i < 10; i++)
- cout << A[i] << " ";
- cout << endl;
-
- mergeSort(A, 0, 9);
-
- for(int i = 0; i < 10; i++)
- cout << A[i] << " ";
- cout << endl;
-
- return 0;
- }
-
- void merge(int A[], int p, int q, int r) {
- int n1 = q - p + 1;
- int n2 = r - q;
- int L[n1 + 1];
- int R[n2 + 1];
-
-
- for(int i = 0; i < n1; i++)
- L[i] = A[p + i];
- for(int i = 0; i < n2; i++)
- R[i] = A[q + 1 + i];
- L[n1] = numeric_limits<int>::max();
- R[n2] = numeric_limits<int>::max();
-
-
- int i = 0, j = 0;
- for(int k = p; k <= r; k++) {
- if(L[i] <= R[j]) {
- A[k] = L[i];
- i++;
- } else {
- A[k] = R[j];
- j++;
- }
- }
- }
-
- void mergeSort(int A[], int p, int r) {
- if(p >= r)
- return ;
-
-
- int q = (p + r) / 2;
-
-
- mergeSort(A, p, q);
- mergeSort(A, q + 1, r);
-
-
- merge(A, p, q, r);
- }