【分治法】---归并排序

分治的基本概念:

      把一个任务,分成形式和原任务相同,但规模更小的几个部分任务(通常是两个部分),分别完成,或只需要选择一部完成。然后再处理完成后的这一个或几个部分的结果,实现整个任务的完成。

      归并排序是典型的分治问题。

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

       将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))的额外空间,时间复杂度为O(nlog(n)),算法不是自适应的,不需要对数据的随机读取。

实现思想:

1、把前一半排序;

2、把后一半排序;

3、把两半归并到一个新的有序数组,然后再拷贝回原数组,排序完成。

算法实现

​void Merge(int a[],int s,int m,int e,int tmp[])//排序
{
    int pb = 0;//tmp[]是周转数组,pb指向tmp[]
    int p1 = s,p2 = m + 1;//p1指向前一半;p2指向后一半
    while(p1 <= m && p2 <= e)
    {
        if(a[p1] < a[p2])//将相对小的放进tmp[]中
        {
            tmp[pb++] = a[p1++];
        }
        else
        {
            tmp[pb++] = a[p2++];
        }

    }
    while(p1 <= m)
    {
        tmp[pb++] = a[p1++];
    }
    while(p2 <= e)
    {
        tmp[pb++] = a[p2++];
    }
    for(int i = 0;i < e - s + 1;i++)
    {
        a[s + i] = tmp[i];
    }
}
void MergeSort(int a[],int s,int e,int tmp[])
{
    if(s < e)
    {
        int m = s + (e - s)/2;
        MergeSort(a,s,m,tmp);
        MergrSort(a,m + 1,e,tmp);
        Merge(a,s,m,e,tmp);
    }
}    ​

猜你喜欢

转载自blog.csdn.net/aby_byy/article/details/88619659