归并排序,递归法,C语言实现。

利用归并排序法对序列排序的示意图(递归法):

一、算法分析:利用递归的分治方法:1、将原序列细分,直到成为单个元素;2、在将分割后的序列一层一层地按顺序合并,完成排序。细分通过不断深入递归完成,合并通过递归   一层层返回完成。

二、C语言代码

  1、完成排序的三个函数

void MergeSort(int l[],int lenght)
{
    int tmp[lenght];

    MSort(l,tmp,1,lenght);
}

/*分:MSort将原来的序列不断细分,直到为1,再由Merge归并*/
void MSort(int l[],int tmp[],int left,int right)
{
    int mid;

    if(left!=right)
    {
        mid=(left+right)/2;     //将待排序序列分成两部分
        MSort(l,tmp,left,mid);      //将左边排序
        MSort(l,tmp,mid+1,right);       //将右边排序
        Merge(l,tmp,left,mid,right);        //将已排序的两部分合并
    }
}

/*数组tmp只是作为临时存储,归并后,再将有序的数组拷贝到原来的l中*/
void Merge(int l[],int tmp[],int left,int mid,int right)
{
    int i,j,t;

    for(i=left,j=mid+1,t=left;i<=mid&&j<=right;t++)
    {
        if(l[i]<=l[j])
        {
            tmp[t]=l[i];
            i++;
        }
        else
        {
            tmp[t]=l[j];
            j++;
        }
    }
    /*归并的两个序列不一样长时,将剩余的元素加入tmp*/
    if(i<=mid)
    {
        for(;i<=mid;i++)
        {
            tmp[t]=l[i];
            t++;
        }
    }
    if(j<=right)
    {
        for(;j<=right;j++)
        {
            tmp[t]=l[j];
            t++;
        }
    }
    /*将归并后的有序序列拷贝到原数组*/
    for(t=left;t<=right;t++)
    {
        l[t]=tmp[t];
    }
}

使用时,调用MergeSort函数就行了

下面是我写的一个测试代码

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define NUM 5000

void MergeSort(int l[],int length);
void MSort(int l[],int tmp[],int left,int right);
void Merge(int l[],int tmp[],int left,int mid,int right);

int main()
{
    int i,a[NUM+1];

    srand((unsigned)time(NULL));
    /*a[0]作为哨兵单元,不在随机数生成之列*/
    for(i=1;i<=NUM;i++)
    {
        a[i]=rand();
    }
    /*printf("Befor sort:");
    for(i=1;i<=NUM;i++)
    {
        printf("%d ",a[i]);
    }*/

    MergeSort(a,NUM);

    printf("
After sort:");
    for(i=1;i<=NUM;i++)
    {
        printf("%d ",a[i]);
    }

    return 0;
}

void MergeSort(int l[],int lenght)
{
    int tmp[lenght];

    MSort(l,tmp,1,lenght);
}

/*分:MSort将原来的序列不断细分,直到为1,再由Merge归并*/
void MSort(int l[],int tmp[],int left,int right)
{
    int mid;

    if(left!=right)
    {
        mid=(left+right)/2;     //将待排序序列分成两部分
        MSort(l,tmp,left,mid);      //将左边排序
        MSort(l,tmp,mid+1,right);       //将右边排序
        Merge(l,tmp,left,mid,right);        //将已排序的两部分合并
    }
}

/*数组tmp只是作为临时存储,归并后,再将有序的数组拷贝到原来的l中*/
void Merge(int l[],int tmp[],int left,int mid,int right)
{
    int i,j,t;

    for(i=left,j=mid+1,t=left;i<=mid&&j<=right;t++)
    {
        if(l[i]<=l[j])
        {
            tmp[t]=l[i];
            i++;
        }
        else
        {
            tmp[t]=l[j];
            j++;
        }
    }
    /*归并的两个序列不一样长时,将剩余的元素加入tmp*/
    if(i<=mid)
    {
        for(;i<=mid;i++)
        {
            tmp[t]=l[i];
            t++;
        }
    }
    if(j<=right)
    {
        for(;j<=right;j++)
        {
            tmp[t]=l[j];
            t++;
        }
    }
    /*将归并后的有序序列拷贝到原数组*/
    for(t=left;t<=right;t++)
    {
        l[t]=tmp[t];
    }
}
原文地址:https://www.cnblogs.com/xmkk/p/3311408.html