排序算法_归并排序


一、算法描述

  将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
  4. 重复步骤3直到某一指针达到序列尾
  5. 将另一序列剩下的所有元素直接复制到合并序列尾

二、图示

      

三、性能描述

  数据结构 :数组

  最差时间复杂度 :O(nlogn)

  最优时间复杂度 :O(n)

  平均时间复杂度 :O(nlogn)

  最差空间复杂度 :O(n)

四、总结

  速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。

五、C++实现代码

View Code
 1 //#只完成兩段之間歸併的功能#%
 2 void Merge(int a[], int b[], int low, int mid, int high)
 3 {
 4     int k = low;
 5     int begin1 = low;
 6     int end1 = mid;
 7     int begin2 = mid + 1;
 8     int end2 = high;
 9     while(k <= high )
10     {
11         if(begin1 > end1)
12             b[k++] = a[begin2++];
13         else if(begin2 > end2)
14             b[k++] = a[begin1++];
15         else
16         {
17             if(a[begin1] <= a[begin2])
18                 b[k++] = a[begin1++];
19             else
20                 b[k++] = a[begin2++];
21         }
22     }
23  
24 }
25  
26 void MergePass(int a[], int b[], int seg, int size)
27 {
28     int seg_start_ind = 0;
29     while(seg_start_ind <= size - 2 * seg) //#size - 2 * seg的意思是滿足可兩兩歸併的最低臨界值#%
30     {
31         Merge(a, b, seg_start_ind, seg_start_ind + seg - 1, seg_start_ind + seg * 2 - 1);
32         seg_start_ind += 2 * seg;
33     }
34     //#如果一段是正好可歸併的數量而另一段則少於正好可歸併的數量#%
35     if(seg_start_ind + seg < size)
36         Merge(a, b, seg_start_ind, seg_start_ind + seg - 1, size - 1);
37     else
38         for(int j = seg_start_ind; j < size; j++) //#如果只剩下一段或者更少的數量#%
39             b[j] = a[j];
40 }
41  
42 void MergeSort(int a[], int size)
43 {
44     int* temp = new int[size];
45     int seg = 1;
46     while(seg < size)
47     {
48         MergePass(a, temp, seg, size);
49         seg += seg;
50         MergePass(temp, a, seg, size);
51         seg += seg;
52     }
53 }
54  
55 int main()
56 {
57     int a[] = {3, 5, 3, 6, 4, 7, 5, 7, 4};
58     MergeSort(a, sizeof(a) / sizeof(*a));
59     //#輸出#%
60     for(int i = 0; i < sizeof(a) / sizeof(*a); i++)
61         cout << a[i] << ' ';
62     cout << endl;
63  
64     return 0;
65 }

参考文档:http://zh.wikipedia.org/wiki/归并排序

优质内容筛选与推荐>>
1、[eclipse]java 查看JDK中底层源码
2、C++ Primer 第3章 字符串、向量和数组
3、极客公园
4、求给定三个点的夹角
5、解决Get和Post请求中中文乱码问题


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn