西西軟件下載最安全的下載網(wǎng)站、值得信賴的軟件下載站!

首頁編程開發(fā)VC|VC++ → 手寫歸并排序算法和sort(),qsort()的比較

手寫歸并排序算法和sort(),qsort()的比較

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來源:西西整理時(shí)間:2013/1/4 21:27:44字體大。A-A+

作者:西西點(diǎn)擊:0次評(píng)論:0次標(biāo)簽: 排序

  • 類型:游戲輔助大。599KB語言:中文 評(píng)分:5.0
  • 標(biāo)簽:
立即下載

早就想寫寫幾個(gè)排序的算法了,原來一直是直接調(diào)用庫函數(shù)sort()和qsort(),導(dǎo)致自己對(duì)它們內(nèi)部是實(shí)現(xiàn)機(jī)理有些忽視,F(xiàn)在就把我剛剛手寫的一個(gè)歸并排序(時(shí)間復(fù)雜度是o(n*log(n))),其中我是用遞歸來實(shí)現(xiàn)的。在代碼中我還比較了手寫歸并,sort(),qsort(),的效率。

先對(duì)程序中所用的數(shù)據(jù)結(jié)構(gòu)做下聲明,方便大家理解接下來的程序:

int res[cnt];
int num1[cnt],num2[cnt],num3[cnt];

其中res是歸并時(shí)用的輔助數(shù)組,num1,num2,num3都是保存的是待排序的數(shù),為了使程序具有可比性,所以把它們的元素賦成相同的值:

void init()
{
    for(int i=0;i<cnt;i++)
    {
        num3[i]=num1[i]=num2[i]=rand();
    }
}

再附上歸并排序的兩個(gè)主要函數(shù)代碼

void merge(int start,int end,int tail)
{
    int i=start,j=end+1;
    int t=start;
    while(i<=end && j<=tail)
    {
        while(i<=end && num1[i]<=num1[j])
        {
            res[t++]=num1[i++];
        }
        while(j<=tail && num1[j]<num1[i])
        {
            res[t++]=num1[j++];
        }
        if(i>end && j<=tail)
        {
            while(j<=tail)
            {
                res[t++]=num1[j++];
            }
            break;
        }
        if(j>tail && i<=end)
        {
            while(i<=end)
            {
                res[t++]=num1[i++];
            }
            break;
        }
    }
    for(int i=start;i<=tail;i++)
    {
        num1[i]=res[i];
    }
}

void mergesort(int l,int r)
{
    if(l==r)
    {
        res[l]=num1[l];
        return ;
    }
    int mid=(l+r)>>1;
    mergesort(l,mid);
    mergesort(mid+1,r);
    merge(l,mid,r);
    return ;
}

主函數(shù)如下:

int main()
{
    init();    
    clock_t clk1,clk2,clk3,clk4,clk5,clk6;
    clk1=clock();
    mergesort(0,cnt-1);
    clk2=clock();
    cout<<"歸并:"<<(double)(clk2-clk1)/CLOCKS_PER_SEC<<endl;
    clk3=clock();
    sort(num2,num2+cnt);
    clk4=clock();
    cout<<"sort:"<<(double)(clk4-clk3)/CLOCKS_PER_SEC<<endl;
    clk5=clock();
    qsort(num3,cnt,sizeof(int),cmp);
    clk6=clock();
    cout<<"qsort:"<<(double)(clk6-clk5)/CLOCKS_PER_SEC<<endl;
    for(int i=0;i<cnt;i++)
    {
        if(num1[i]!=num2[i] || num1[i]!=num3[i])
        {
            cout<<"not equal"<<endl;
            cout<<setprecision(4)<<num1[i]<<"  "<<num2[i]<<"  "<<num3[i]<<" "<<i<<endl;
            break;
        }
    }
    system("pause");
    return 0;
}

最后的那個(gè)循環(huán)主要是為了用來判斷我手寫代碼的正確性。

最后我們來看一下比較效率的結(jié)果(這里通過改變cnt的數(shù)量級(jí),來經(jīng)行多組對(duì)比):

當(dāng)cnt=50000時(shí)的輸出為:

歸并:0.018
sort:0.099
qsort:0.039

當(dāng)cnt=500000時(shí)的輸出為:

歸并:0.181
sort:1.066
qsort:0.393

當(dāng)cnt=5000000時(shí)的輸出為:

歸并:1.931
sort:9.484
qsort:3.881

從以上三組數(shù)據(jù)可以看出它們之間的效率關(guān)系為:sort()<qsort()<手寫歸并,回到理論上它們?nèi)齻(gè)的平均時(shí)間復(fù)雜度都是o(n*log(n)),可是在這里出現(xiàn)的差別還是比較大的。記得原來做ACM的時(shí)候經(jīng)常會(huì)聽到有人說sort()要比qsort()高效,但這里的結(jié)果卻與這個(gè)說法不相符。

開始我是懷疑排序元素類型的原因,不過換了double試了一下,還是同樣的結(jié)果,不過換用double有點(diǎn)換湯不換藥的感覺,大家如有有興趣的話可以用string類型試試。

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過審核才能顯示)
    推薦文章

    沒有數(shù)據(jù)

      沒有數(shù)據(jù)
    最新文章
      沒有數(shù)據(jù)