冒泡排序中交换次数与比较次数

来源:互联网 发布:珠海办公软件培训 编辑:程序博客网 时间:2024/06/08 14:09

冒泡排序的过程中每次交换就是消除一个逆序对,而比较次数由其外层循环确定,因为内层是肯定循环至结束的。

用了归并排序求逆序对,树状数组求一个数的最大逆序对数。内部循环的次数为n-1,n-2.....n-m 数列求和。

代码如下,大家可以测试下。



#include<cstdio>#include<iostream>#include<cstdlib>#include<cstring>#include<ctime>#define lowbit(x) (-x)&(x)#define N 110#define M 100using namespace std;int num[N];int use[N];int tmp[N];int vis[N];int sum[N];int antinum;void mergesort(int l,int r)//归并排序求逆序数{    if(l>=r) return;    int mid=(l+r)>>1;    mergesort(l,mid);    mergesort(mid+1,r);    int st=l,mt=mid+1,k=l;    while(st<=mid && mt<=r)    {        if(tmp[st]<=tmp[mt])            use[k++]=tmp[st++];        else            use[k++]=tmp[mt++],antinum+=mid-st+1;    }    while(st<=mid)        use[k++]=tmp[st++];    while(mt<=r)        use[k++]=tmp[mt++];    while(l<=r)        tmp[l]=use[l],l++;}void up(int n,int x){    while(n<=M)    {        sum[n]+=x;        n+=lowbit(n);    }}int getsum(int n){    int res=0;    while(n>0)    {        res+=sum[n];        n-=lowbit(n);    }    return res;}int main(){    srand( time(NULL) );    antinum=0;    memset(vis,0,sizeof(vis));    for(int i=1;i<=M;i++)    {        int x=rand()%M+1;        if(vis[x]) {i--;continue;}        vis[x]=1;        num[i]=x,tmp[i]=x;        cout<<x<<endl;    }    int antimax=0;    for(int i=1;i<=M;i++)//树状数组求一个数的最大逆序数对    {        antimax=max(antimax,i-getsum(num[i]-1));        up(num[i],1);    }    mergesort(1,M);    int m=antimax*(2*M-1-antimax)/2;    int u=0,v=0;    for(int i=1;i<M;i++)    {        int tag=1;        for(int j=1;j<M-i+1;j++,v++)            if(num[j]>num[j+1]) u++,swap(num[j],num[j+1]),tag=0;        if(tag) break;    }//正常的冒泡,以便比较结果 冒泡写错好几次    cout<<u<< " "<<v<<endl;    cout<<antinum<<" "<< m<<endl;    return 0;}

0 0
原创粉丝点击