排序算法之合并排序

合并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

算法思路:

     若n为1,算法终止;否则,将n个待排元素分割成k(k=2)个大致相等子集合A、B,对每一个子集合分别递归排序,再将排好序的子集归并为一个集合。

分为两部分:

一.递归算法

排序算法之合并排序_第1张图片

二.归并排序

排序算法之合并排序_第2张图片

C++代码(百度百科)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//C++
#include
#include
using  namespace  std; //合并排序
//合并两部分有序数组time:O(n)
template < typename  T>
void  Merge(T  *arry, int  start, int  p, int  end)
{
     int  lsize=p-start,rsize=end-p; //两个数组的大小
     T * l= new  T[lsize],*r= new  T[rsize]; //要合并的两个数组
     memcpy (l,arry + start, sizeof (T)*lsize);
     memcpy (r,arry + p, sizeof (T)*rsize); //将要合并的数组复制
     int  lnow=0,rnow=0,i; //未合并的数字的位置
     for (i=0;lnow
     {
         if (l[lnow]>r[rnow]) //取较大的数
         {
             arry[start+i]=l[lnow];
             lnow++;
         }
         else
         {
             arry[start+i]=r[rnow];
             rnow++;
         }
     }
     if (lnow==lsize&&rnow!=rsize) //其中一个数组合并完以后,复制剩下的数据
     {
         memcpy (arry+start+i,r+rnow, sizeof (T)*(rsize-rnow));
     }
     else  if (rnow==rsize&&lnow!=lsize)
     {
         memcpy (arry+start+i,l+lnow, sizeof (T)*(lsize-lnow));
     }
     delete  l;
     delete  r; //清理内存
     //return ;
} //排序函数time:O(nlgn)
template < typename  T>
void  MergeSort(T *arry, int  start, int  end)
{
     if (end-start > 1) //当元素个数为1时直接返回
     {
         int  p=(start + end)/2; //切割数组
         MergeSort(arry,start,p);
         MergeSort(arry,p,end); //分别排序
         Merge(arry,start,p,end); //合并数组
     }
}
int  main()
{
      
     int  arr[10]={7,3,4,7,10,9,1,5,3,7};
     
     MergeSort(arr,0,10);
     for ( int  i=0;i<10;i++)
     {
         cout< " " <
     }
     return  0;
}
合并排序的效率分析

基本操作??
似乎较难判断。
写出总体工作量表达式。

设n=2k, 总工作量表示为:
C(n)=(1次除法)+2Ccopy(n/2)+2C(n/2)+Cmerge(n)
C(1)=0
简写为 C(n)=2C(n/2)+Cmerge(n)+kn

基本操作
比较?拷贝?
(比较的次数不会大于拷贝的次数)
是否和其他因素相关?
最坏情况如何?
归并排序的效率Cmerge(n)=n,
C (n)=2C(n/2)+sn
解得
           C(n)=nlog2n-n+1∈Θ(nlog2n)

合并排序结论

最坏情况Θ(nlog2n)
优点:
合并排序在最坏情况下的键值比较次数十分接近于任何基于比较的排序算法在理论上能够达到的最少次数
合并排序精确解Cworst(n)=nlog2n-n+1
理论最小值nlog2n-1.44n向上取整
缺点:
需要线性的额外空间,体现在何处?
虽然合并也可做到“在位”,但导致算法过于复杂。

你可能感兴趣的:(算法)