归并排序

转载至https://www.cnblogs.com/chengxiao/p/6194356.html(这里是C++版本)

基本思想

  归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

分而治之

   可以看到这种结构很像一棵完全二叉树,本文的归并排序我们采用递归去实现(也可采用迭代的方式去实现)。阶段可以理解为就是递归拆分子序列的过程,递归深度为log2n。

合并相邻有序子序列

  再来看看阶段,我们需要将两个已经有序的子序列合并成一个有序序列,比如上图中的最后一次合并,要将[4,5,7,8]和[1,2,3,6]两个已经有序的子序列,合并为最终序列[1,2,3,4,5,6,7,8],来看下实现步骤。

代码实现

 1 #include<iostream>
 2 #include<cstring>
 3 
 4 using namespace std; 
 5 
 6 // 合并 
 7 void merge(int *a, int l, int mid, int r, int *temp) 
 8 {
 9     int i = l;        // 左序列指针 
10     int j = mid+1;    //
11     int t = 0;        // 临时数组指针 
12     while(i <= mid && j <= r){
13         if(a[i] <= a[j]) temp[t++] = a[i++];
14         else temp[t++] = a[j++];
15     }
16     // 将左边的剩余元素填入 temp 
17     while(i <= mid) temp[t++] = a[i++];
18     //
19     while(j <= r) temp[t++] = a[j++];
20     // 将 temp 中的袁术拷入原始数组中 
21     t = 0;
22     while(l <= r) a[l++] = temp[t++];
23 }
24 
25 // 归并排序 
26 void merge_sort(int *a, int l, int r, int *temp)
27 {
28     if(l < r){    // 分治法 
29         int mid = (l + r)/2;
30         merge_sort(a, l, mid, temp);
31         merge_sort(a, mid+1, r, temp);
32         merge(a, l, mid, r, temp);
33     }
34 }
35 
36 int main()
37 {
38     int a[] = {1, 3, 2, 4, 5, 8, 6, 7, 9};
39     int r = sizeof(a)/sizeof(int) - 1;
40     int temp[r+1];
41     memset(temp, 0, sizeof(temp));
42     merge_sort(a, 0, r, temp);
43     
44     for(int i=0;i<9;i++)
45         cout<<a[i]<<" ";
46     cout<<'
'; 
47     
48     return 0;
49 }
View Code
原文地址:https://www.cnblogs.com/mabeyTang/p/10415087.html