对比 几种 排序算法 的 比较次数

今天在实际项目中遇到了一个排序问题,对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:\t"<<count<<endl;
    count=SelectSort(num);
    cout<<"SelectSort:\t"<<count<<endl;
    count=InsertSort(num);
    cout<<"InsertSort:\t"<<count<<endl;
    count=MergeSort(num);
    cout<<"MergeSort:\t"<<count<<endl;
    count=QuickSort(num);
    cout<<"QuickSort:\t"<<count<<endl;


    return 0;
}

 

posted @ 2013-09-25 23:30  bird_beginning  阅读(4011)  评论(0编辑  收藏  举报