归并排序(Merge Sort)+计算数列逆序数

来源:互联网 发布:手机电信网络加速器 编辑:程序博客网 时间:2024/04/30 12:44

首先是这个算法的基本过程和思想:就是先把一个数列分成两部分,再接着把分成两部分的数列分别再分成两部分,直到分到不能再次分为止,也就是一个数列里面只有一个数的时候。

最后我们把它们两两合并,在合并的时候,从个数为1的数列合并,这个比较好合并,变成了一个个数是2,并且有序的数组,在合并两个个数比较多的数列的时候我们已经知道它是有序的并且这两个数组的有序方式都是一样的(要么都升序,要么都逆序),这个时候我们从两个数组的最左边两个数中拿其中一个相对小的数放到我们的某个数组中,这样最后我们肯定就能把左右的数组都合并起来成为一个最后的具有顺序的大的数组,下面是示例代码:

#include <iostream>using namespace std;#define MAX_SIZE 100;int a[MAX_SIZE];int temp[MAX_SIZE];int cnt=0;void MergeSort(int a[],int l,int mid,int r){    //i从左边的数组的第一个下标开始遍历    //j从右边的第一个下标开始遍历,因为这两个子数列在原数组a中是连续的,所以右边数组的第一个下标是mid+1    int i=l,j=mid+1,length=r-l+1;    //temp数组的下标变量k,从0开始的。    int k=0;    while (i<=mid&&j<=r)    {        if (a[i]>a[j])        {            temp[k++]=a[j++];            cnt+=mid-l+1;        }        else            temp[k++]=a[i++];    }    //上面的while语句,把左边的数组或者右边的数组全部赋值到temp数组中了    //但是不一定恰好两个数组都全部赋值完,这个时候需要把没有赋值完的数组再进行一次赋值    //这时我们可以根据i和j的值来判断哪个数组没赋值完。    if(i<=mid&&j>r)    {        while (i<=mid) temp[k++]=a[i++];    }    else    {        while (j<=r) temp[k++]=a[j++];    }    //这个时候,temp数组里面的数是有顺序的。因此我们可以把temp中的数组放到a数组中去。    for (k=0;k<r-l+1;k++)        a[l+k]=temp[k];}void Merge(int a[],int l,int r){    if (l<r)    {        int mid=(l+r)/2;        //分l到mid的子数组,再调用一次这个函数        Merge(a,l,mid);        //分mid+1到r的子数组,再调用一次这个函数        Merge(a,mid+1,r);        //最后利用一个MergSort()来将已经分开的函数进行整合,也就是将他们合并起来        //这个函数调用的4个参数里面 用3个下标就知道我们需要合并的子数组是什么。        MergeSort(a,l,mid,r);    }}int main(){    int n;    while (cin>>n)    {        for (int i=1;i<=n;i++)            cin>>a[i];        Merge(a,1,n);        for (int i=1;i<=n;i++)            cout<<a[i]<<" ";        cout<<endl;    }    return 0;}/*text data:512 9 34 21 73*/

嘻嘻,大家就凑活着看吧,我是小白,可能代码还有不太好的地方,请多多指教,以上的讲解,全是我个人的理解。

0 0