归并排序

ぐ巨炮叔叔 提交于 2020-01-19 22:38:04

归并排序

1.简单介绍:

采用的叫分治的思想,将数组划分为两个子数组,然后递归将每个子数组再进行划分,直到数组中只剩一下一个元素,然后开始排序合并,直到将所有的子数组合并完成,整个数据就是有序的啦。时间复杂度:NlogN。

2.原理

图解

思路:先将无序序列利用二分法划分为两个子序列,直至每个子序列只有一个元素,一个元素序列必然有序,然后再对有序子序列两两进行合并排序。合并方法是循环的将两个有序子序列当前的首元素进行比较,较小的元素取出,放入合并序列的左边空置位,直至其中一个子序列的最后一个元素放入合并序列中。最后将另一个子序列的剩余元素按顺序逐个放入合并序列尾部。

3.代码:

排序过程:

int c[1000],a[1000];
void  paixu(int a[1000],int l,int mid,int r)
{
    long long int i=l,j=mid+1,k=0;
    while(i<=mid&&j<=r)
    {
        if(a[i]<=a[j])
            c[k++]=a[i++];
        else
        {
            m+=mid-i+1;
            c[k++]=a[j++];
        }

    }
    while(i<=mid)
        c[k++]=a[i++];
    while(j<=r)
        c[k++]=a[j++];
    for(i=l;i<=r;i++)
    {
        a[i]=c[i-l];
    }
}

归并过程

void merge(int a[1000],int l,int r)
{
    int mid;
    if(l==r)
        return;

        mid=(l+r)/2;
        merge(a,l,mid);
        merge(a,mid+1,r);
        paixu(a,l,mid,r);
}

4.例题:

求逆序数。

样例

样例输入 Copy

2
2
1 1
3
1 3 2

样例输出 Copy

0
1	

在归并的基础上加上sum即可

代码:

#include<stdio.h>
long long int sum=0;
long long int c[10000],a[10000];
void  paixu(long long int a[],long long int l,long long int mid,long long int r)
{
    int i=l,j=mid+1,k=l;
    while(i<=mid&&j<=r)
    {
        if(a[i]<=a[j])
         c[k++]=a[i++];
        else
        {
            c[k++]=a[j++];
            sum+=mid-i+1;
        }
    }
    while(i<=mid)
        c[k++]=a[i++];
    while(j<=r)
        c[k++]=a[j++];
    for(i=l;i<=r;i++)
    {
        a[i]=c[i];
    }
}
void merge(long long int a[],long long int l,long long int r)
{
    long long int mid;
    if(l<r)
     {
        mid=(l+r)/2;
        merge(a,l,mid);
        merge(a,mid+1,r);
        paixu(a,l,mid,r);
     }

}
int main()
{
    long long int n,i,t;
    scanf("%lld",&t);
    while(t--)
    {
        sum=0;
        scanf("%lld",&n);
        for(i=0;i<n;i++)
    {
        scanf("%lld",&a[i]);
    }
    merge(a,0,n-1);
    printf("%lld\n",sum);
    }
    return 0;
}

5.心得:又了解到一个新的排序方法,与之前学到的相比时间复杂度要小,解题时可根据时间限制,和题目所需巧用各种排序方法。
 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!