合并排序

合并排序使用了“分治法”的策略。

“将原问题划分成n个规模较小而结构与原问题相似的子问题;递归地解决这些子问题;然后合并其结果,就得到原问题的解。”这就是分治策略。

分治策略在每一层递归上有以下三个步骤:

1)分解:将原问题分解成一系列子问题;

2)解决:递归地解各子问题;

3)合并:将子问题的解合并成原问题的解。

 

合并排序依照上述策略:

1)分解:将n个元素分成两个含n/2个元素的子序列;

2)解决:用合并排序法对两个子序列递归地排序;

3)合并:合并两个已排序的子序列以得到排序结果。

 

以下代码演示了合并排序算法:

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include <limits>  
  3.   
  4. using namespace std;  
  5.   
  6. /*合并A[p...q]和A[q+1...r]数组,初始条件为两个字数组均有序,合并后A[p...r]有序*/  
  7. void merge(int A[], int p, int q, int r);  
  8. /*合并排序,排序后,A[p...r]为非递减数组*/  
  9. void mergeSort(int A[], int p, int r);  
  10.   
  11. int main() {  
  12.     int A[10] = {20, 31, 14, 5, 11, 7, 83, 3, 5, 67};  
  13.   
  14.     for(int i = 0; i < 10; i++)  
  15.         cout << A[i] << " ";  
  16.     cout << endl;  
  17.   
  18.     mergeSort(A, 0, 9);  
  19.   
  20.     for(int i = 0; i < 10; i++)  
  21.         cout << A[i] << " ";  
  22.     cout << endl;  
  23.   
  24.     return 0;  
  25. }  
  26.   
  27. void merge(int A[], int p, int q, int r) {  
  28.     int n1 = q - p + 1; //字数组A[p...q]长度  
  29.     int n2 = r - q; //字数组A[q+1...r]长度  
  30.     int L[n1 + 1]; //辅助数组  
  31.     int R[n2 + 1]; //辅助数组  
  32.   
  33.     /*初始化*/  
  34.     for(int i = 0; i < n1; i++)  
  35.         L[i] = A[p + i];  
  36.     for(int i = 0; i < n2; i++)  
  37.         R[i] = A[q + 1 + i];  
  38.     L[n1] = numeric_limits<int>::max(); //末端置最大值,作哨兵  
  39.     R[n2] = numeric_limits<int>::max(); //同上  
  40.   
  41.     /*以下循环将L,R字数组合并到A数组*/  
  42.     int i = 0, j = 0;  
  43.     for(int k = p; k <= r; k++) {  
  44.         if(L[i] <= R[j]) {  
  45.             A[k] = L[i];  
  46.             i++;  
  47.         } else {  
  48.             A[k] = R[j];  
  49.             j++;  
  50.         }  
  51.     }  
  52. }  
  53.   
  54. void mergeSort(int A[], int p, int r) {  
  55.     if(p >= r)  
  56.         return ; //结束条件  
  57.   
  58.     /*分解*/  
  59.     int q = (p + r) / 2; //取“中间”数作为分界点  
  60.   
  61.     /*解决*/  
  62.     mergeSort(A, p, q); //递归排序  
  63.     mergeSort(A, q + 1, r); //同上  
  64.   
  65.     /*合并*/  
  66.     merge(A, p, q, r);  
  67. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值