zoukankan      html  css  js  c++  java
  • 对比 几种 排序算法 的 比较次数

    今天在实际项目中遇到了一个排序问题,对Object排序,其中比较操作特别耗时,而交换操作的时间可以忽略不计,这样就不能用之前一直了解的最佳实践的快速排序了,得重新评价各种排序算法的比较次数,因此做了以下实验:对比了在处理相同长度的随机数组排序时,各种排序的比较次数:

    实验结果输出如下:(注:里面InsertSort使用的是二分插入排序)

    10 numbers:
    BubbleSort:     30
    SelectSort:     45
    InsertSort:     21
    MergeSort:      24
    QuickSort:      22
    
    100 numbers:
    BubbleSort:     3725
    SelectSort:     4950
    InsertSort:     523
    MergeSort:      547
    QuickSort:      633
    
    1000 numbers:
    BubbleSort:     374250
    SelectSort:     499500
    InsertSort:     8576
    MergeSort:      8716
    QuickSort:      11403
    
    10000 numbers:
    BubbleSort:     37487499
    SelectSort:     49995000
    InsertSort:     117629
    MergeSort:      120386
    QuickSort:      157664
    
    100000 numbers:
    BubbleSort:     -544992296
    SelectSort:     704982704
    InsertSort:     1391899
    MergeSort:      1536293
    QuickSort:      2061112

    从实验结果可以看出,实践最好的是二分插入排序,有最少的比较次数。

    其次是归并排序,最快排序表现一般,而那两个O(n^2)的就明显差得远了(100000时他们溢出了)

    附代码:

    #include<iostream>
    #include<cstdio>
    #include<ctime>
    using namespace std;
    
    const int LENGTH=100000;
    const int Max_num=65535123;
    
    void printNums(int *pnum,int l)
    {
        for(int i=0;i<l;i++)
        {
            cout<<pnum[i]<<" ";
        }
        cout<<endl;
    }
    
    
    
    int BubbleSort(int* pnum)
    {
        int sorting[LENGTH];
        for(int i=0;i<LENGTH;i++)
        {
            sorting[i]=pnum[i];
        }
        int compareCount=0;
        //sort
        for(int i=LENGTH-1;i>0;i--)
        {
    
            int changeCount=0;
            for(int j=i;j>0;j--)
            {
                compareCount++;
                if(sorting[j]<sorting[j-1])
                {
                    sorting[j]^=sorting[j-1];
                    sorting[j-1]^=sorting[j];
                    sorting[j]^=sorting[j-1];
                    changeCount++;
                }
            }
            if(!changeCount)
            {
                break;
            }
        }
    
        //printNums(sorting,LENGTH);
        return compareCount;
    }
    
    int SelectSort(int* pnum)
    {
        int sorting[LENGTH];
        for(int i=0;i<LENGTH;i++)
        {
            sorting[i]=pnum[i];
        }
        int compareCount=0;
        
        //sort
        for(int i=0;i<LENGTH-1;i++)
        {
            int t=i;
    
            for(int j=i+1;j<LENGTH;j++)
            {
                compareCount++;
                if(sorting[j]<sorting[t])
                    t=j;
            }
    
            if(t!=i)
            {
                sorting[t]^=sorting[i];
                sorting[i]^=sorting[t];
                sorting[t]^=sorting[i];
            }
        }
    
    
        //printNums(sorting,LENGTH);
    
        return compareCount;
    }
    
    int InsertSort(int* pnum)
    {
        int sorting[LENGTH];
        for(int i=0;i<LENGTH;i++)
        {
            sorting[i]=pnum[i];
        }
        int compareCount=0;
    
        //sort
        for(int i=1;i<LENGTH;i++)
        {
            int beginIndex=0;
            int endIndex=i-1;
            int pos=-1;
            while(beginIndex<=endIndex)
            {
                int middleIndex=(beginIndex+endIndex)/2;
                compareCount++;
                if(sorting[i]>sorting[middleIndex])
                {
                    beginIndex=middleIndex+1;
                    if(beginIndex>endIndex)
                    {
                        pos=endIndex+1;
                    }
                }
                else if(sorting[i]<sorting[middleIndex])
                {
                    endIndex=middleIndex-1;
                    if(beginIndex>endIndex)
                    {
                        pos=beginIndex;
                    }
                }
                else
                {
                    pos=middleIndex+1;
                    break;
                }
            }
    
            if(pos>=0&&pos<i)
            {
                int temp=sorting[i];
                for(int j=i-1;j>=pos;j--)
                {
                    sorting[j+1]=sorting[j];
                }
                sorting[pos]=temp;
            }
        }
    
        //printNums(sorting,LENGTH);
    
        return compareCount;
    
    }
    
    
    int merge(int *pnum,int p,int q,int r)
    {
        int count=0;
    
        int n1=q-p+1;
        int n2=r-q;
        int* pL=new int[n1];
        int* pR=new int[n2];
    
        for(int i=0;i<n1;i++)
        {
            pL[i]=pnum[p+i];
        }
        for(int i=0;i<n2;i++)
        {
            pR[i]=pnum[q+i+1];
        }
    
        //pL[n1]=Max_num;
        //pR[n2]=Max_num;
        int i,j,k;
        for(i=0,j=0,k=p;k<=r;k++)
        {
            count++;
            if(pL[i]<=pR[j])
            {
                pnum[k]=pL[i++];
                if(i>=n1)
                {
                    for(;k<r;k++)
                    {
                        pnum[k+1]=pR[j++];
                    }
                    break;
                }
            }
            else
            {
                pnum[k]=pR[j++];
                if(j>=n2)
                {
                    for(;k<r;k++)
                    {
                        pnum[k+1]=pL[i++];
                    }
                    break;
                }
            }
        }
    
    
        return count;
    }
    
    int merge_sort(int *pnum,int p,int r)
    {
        int count=0;
        if(p<r)
        {
    
            int q=(p+r)/2;
            count+=merge_sort(pnum,p,q);
            count+=merge_sort(pnum,q+1,r);
            count+=merge(pnum,p,q,r);
            
        }
        return count;
    }
    
    int MergeSort(int *pnum)
    {
        int sorting[LENGTH];
        for(int i=0;i<LENGTH;i++)
        {
            sorting[i]=pnum[i];
        }
        int compareCount=0;
    
        //sort
        compareCount=merge_sort(sorting,0,LENGTH-1);
    
        //printNums(sorting,LENGTH);
        return compareCount;
    }
    
    
    int partition(int *pnum,int p,int r,int &q)
    {
        int count=0;
        int x=pnum[r];
        int i=p-1;
        for(int j=p;j<r;j++)
        {
            count++;
            if(pnum[j]<=x)
            {
                i++;
                int t=pnum[i];
                pnum[i]=pnum[j];
                pnum[j]=t;
            }
        }
        int t=pnum[i+1];
        pnum[i+1]=pnum[r];
        pnum[r]=t;
        q=i+1;
        return count;
    }
    
    int quick_sort(int *pnum,int p,int r)
    {
        int count=0;
        if(p<r)
        {
            int q=-1;
            count+=partition(pnum,p,r,q);
            count+=quick_sort(pnum,p,q-1);
            count+=quick_sort(pnum,q+1,r);
        }
        return count;
    }
    
    int QuickSort(int *pnum)
    {
        int sorting[LENGTH];
        for(int i=0;i<LENGTH;i++)
        {
            sorting[i]=pnum[i];
        }
        int compareCount=0;
        //printNums(sorting,LENGTH);
        //sort
        compareCount=quick_sort(sorting,0,LENGTH-1);
    
        //printNums(sorting,LENGTH);
        return compareCount;
    }
    
    
    
    int main()
    {
        srand((unsigned int)time(0));
        int num[LENGTH];
        memset(num,0,sizeof(num));
        for(int i=0;i<LENGTH;i++)
        {
            num[i]=rand()%Max_num;
        }
                 
        cout<<LENGTH<<" numbers:"<<endl;
    
        int count=BubbleSort(num);
        cout<<"BubbleSort:	"<<count<<endl;
        count=SelectSort(num);
        cout<<"SelectSort:	"<<count<<endl;
        count=InsertSort(num);
        cout<<"InsertSort:	"<<count<<endl;
        count=MergeSort(num);
        cout<<"MergeSort:	"<<count<<endl;
        count=QuickSort(num);
        cout<<"QuickSort:	"<<count<<endl;
    
    
        return 0;
    }
  • 相关阅读:
    设计模式之单例模式(Singleton)
    ASP.Net WebForm温故知新学习笔记:二、ViewState与UpdatePanel探秘
    ASP.Net WebForm温故知新学习笔记:一、aspx与服务器控件探秘
    [学习笔记] $Maximum$ $Minimum$ $identity$
    BZOJ 2159: Crash 的文明世界(组合数学+第二类斯特林数+树形dp)
    BZOJ 3083: 遥远的国度 (树剖+线段树)
    LUOGU P4560 [IOI2014]Wall 砖墙 (线段树)
    牛客网 NOIP赛前集训营-普及组(第四场)C--部分和 (高维前缀和)
    LUOGU P1501 [国家集训队]Tree II (lct)
    LUOGU P3690 【模板】Link Cut Tree (lct)
  • 原文地址:https://www.cnblogs.com/cloudssdut/p/3339922.html
Copyright © 2011-2022 走看看