归并排序

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

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。


基本思想

将待排序序列R[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,得到n/2个长度为2的有序表;将这些有序序列再次归并,得到n/4个长度为4的有序序列;如此反复进行下去,最后得到一个长度为n的有序序列。
综上可知:

具体操作:

(1)“分解”——将序列每次折半划分。
(2)“合并”——将划分后的序列段两两合并后排序。


子序列合并

在每次合并过程中,都是对两个有序的序列段进行合并,然后排序。

这两个有序序列段分别为 r[low, mid] 和 r[mid+1, high]。
为了方便描述,我们称 r[low, mid] 第一段,r[mid+1, high] 为第二段。
每次从两个段中取出一个记录进行关键字的比较,将较小者放入rf中。最后将各段中余下的部分直接复制到rf中。
经过这样的过程,rf已经是一个有序的序列。

归并排序示意图:

归并排序_第1张图片

实现代码:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void merge(int r[],int rf[],int u,int v,int t)      //将有序r[u...v]和r[v+1...t]归并到rf[u...t]中
{
    int i,j,k;
    for(i=u,j=v+1,k=u;i<=v&&j<=t;k++)       //每次从有序r[u...v]和r[v+1...t]中取出一个最小值依次放到rf中
    {
        if(r[i]<r[j])
        {
            rf[k]=r[i];i++;
        }
        else
        {
            rf[k]=r[j];j++;
        }
    }
        while(i<=v)         //将剩余r[i...v]复制到rf
        {
            rf[k++]=r[i++];
        }
        while(j<=t)         //将剩余r[j...v]复制到rf
        {
            rf[k++]=r[j++];
        }
    
}

归并排序

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
void msort(int p[],int p1[],int n,int t)        //将p[n...t]归并排序为p1[n...t]
{
    int m;
    int p2[MAXSIZE ];       //中间变量,存放部分排序结果
    if(n==t) p1[n]=p[n];        //p只有一个元素时
    else    
    {
        m=(n+t)/2;      //分解成两部分
        msort(p2,n,m);      //将p[n...m]归并为有序p2[n...m]
        msort(p2,m+1,t);        //将p[m+1...t]归并为有序p2[m+1...t]
        merge(p2,p1,n,m,t);     //将p2[n...m]和p2[m+1...t]合并到p1[n...t]
    }
}


转载自:http://www.cnblogs.com/jingmoxukong/p/4308823.html

你可能感兴趣的:(归并排序,C语言,排序算法)