快速排序和归并排序

快速排序
选择一个枢纽,将比它小的放在它前面,将比它大的放在它后面,然后分解数组,直到数组不能再分(从小到大排序)。若是想得到从大到小排序的数组,只需将比枢纽大的放在它前面,比枢纽小的放在它后面,其余操作依旧。
代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
void Qsort(int a[],int low,int high)
{
    if(low>=high)
    {
        return ;
    }
    int first=low;
    int last=high;
    int key=a[first];   //数组中第一个记为枢轴
    while(first<last)
    {
        while(first<last&&a[last]>=key)
        {
            --last;
        }
        a[first]=a[last];   //将比第一个小的移到低端
        while(first<last&&a[first]<=key)
        {
            ++first;
        }
        a[last]=a[first];   //将比第一个大的移到高端
    }
    a[first]=key;    //枢轴记录到位
    Qsort(a,low,first-1);
    Qsort(a,first+1,high);
}
int main()
{
    int n;
    int a[100005];
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        Qsort(a,0,n-1);
        for(int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}


归并排序
利用划分操作将序列分为元素个数尽量相等的两半,不停划分直至元素不可再分,然后利用递归操作将两半元素排序,最后利用类似插入排序的操作将两半元素合并。
代码如下

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
void merge_sort(int a[],int t[],int x,int y)
{
    if(y-x>1)
    {
        int m=x+(y-x)/2;        //划分
        int p=x,q=m,i=x;
        merge_sort(a,t,x,m);    //递归求解
        merge_sort(a,t,m,y);    //递归求解
        while(p<m||q<y)
        {
            if(q>=y||(p<m&&a[p]<=a[q]))
            {
                t[i++]=a[p++];
            }          //从左半数组复制到临时空间
            else
            {
                t[i++]=a[q++];
            }          //从右半数组复制到临时空间
        }
        for(i=x;i<y;i++)
        {
            a[i]=t[i];   //从辅助空间复制回a数组
        }
    }
}
int main()
{
    int a[100005];
    int t[100005];
    int n;
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        merge_sort(a,t,0,n);
        for(int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}


归并排序求逆序对数
代码如下

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
void merge_sort(int a[],int t[],int x,int y,int& ans)
{
    if(y-x>1)
    {
        int m=x+(y-x)/2;        //划分
        int p=x,q=m,i=x;
        merge_sort(a,t,x,m,ans);    //递归求解
        merge_sort(a,t,m,y,ans);    //递归求解
        while(p<m||q<y)
        {
            if(q>=y||(p<m&&a[p]<=a[q]))
            {
                t[i++]=a[p++];
            }          //从左半数组复制到临时空间
            else
            {
                t[i++]=a[q++];
                ans+=m-p;  //累加每个元素左边比自己大的数的个数
            }          //从右半数组复制到临时空间
        }
        for(i=x;i<y;i++)
        {
            a[i]=t[i];   //从辅助空间复制回a数组
        }
    }
}
int main()
{
    int a[100005];
    int t[100005];
    int n;
    while(cin>>n)
    {
        int ans=0;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        merge_sort(a,t,0,n,ans);
        cout<<ans<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值