快速排序(Quick sort)

在《編程珠璣》中看到作者的的quick sort的速度介於C的qsort和C++的sort之間。
經過3次調優之後始終比C++的sort慢。我在作者的基礎上又進行了若干次調優後,
速度和C++的sort基本持平。

所作的改變是將數組版改成指針版,這使速度得到明顯的提升。
顯然指針效率更高!

我只使用遞歸版本,因爲在我的機器上遞歸版本和迭代版本沒有明顯差異,
原因可能有兩個:(1)打開編譯器優化開關後,編譯器將尾部遞歸自動轉成迭代;
(2)1百萬個元素排序至多遞歸40次,開銷不大。

我測試用的系統是:
OS:       fedora 11(kernel:2.6.29.4-167.fc11.i686.PAE)
Compiler: g++ (GCC) 4.4.0 20090506 (Red Hat 4.4.0-4)
Memory:   2G
CPU:      Intel(R) Core(TM)2 Duo CPU     E7500  @ 2.93GHz


程序編譯:
1 使用 STL sort 版本:
    g++ -g -O2 -W -Wall -Wextra -o mytest -DUSE_STLSORT main.cpp

2 使用我的 quick sort 版本:
    g++ -g -O2 -W -Wall -Wextra -o mytest main.cpp

如果要看結果,編譯時加 -DCOLL_PRINT 選項(打開此選項速度會變慢很多)。


程序執行:
命令 time ./mytest查看程序執行所用時間。

平均時間兩者都在0m0.115s左右!

下面是代碼, 我只將最後的版本貼在這裏,你可以自己改回數組版,看看速度的差異:

//////////////////////////////////////////////////////////////////////////////////////

main.cpp:

// 2010年 10月 11日 星期一 09:29:26 CST
// author: 李小丹(Li Shao Dan) 字 殊恆(shuheng)
// K.I.S.S
// S.P.O.T
// for test sort

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <algorithm>

using namespace std;

#define MAX_NUMBER 1000000
#define MAX_VALUE 6000000
#define SORT_THRESHOLD 48

//#define USE_STLSORT
//#define COLL_PRINT

#ifndef USE_STLSORT
static void quick_sort(int *, int *);
static void insert_sort(int *, int *);
#endif

#ifdef COLL_PRINT
static void print_coll(int *, int);
#endif

int main()
{
    srand(time(0));
    int *coll = new int[MAX_NUMBER];
    for(int i = 0; i < MAX_NUMBER; ++i)
        coll[i] = rand() % MAX_VALUE;

#ifdef USE_STLSORT
#warning Use STL sort

    sort(coll, coll + MAX_NUMBER);

#else
#warning Use my sort

    quick_sort(coll, coll + MAX_NUMBER);
    //insert_sort(coll, coll + MAX_NUMBER);

#endif

#ifdef COLL_PRINT
    print_coll(coll, MAX_NUMBER);
#endif

    delete [] coll;
    return 0;
}


#ifndef USE_STLSORT

#define SWAP(a, b, t)    (t) = (a); (a) = (b); (b) = (t);
static void quick_sort(int *bp, int *ep)
{
    int n = ep - bp;
    if(n > SORT_THRESHOLD) {
        int t;
        int *qp = bp + (n >> 1);
        SWAP(*bp, *qp, t)

        int qv = *bp;
        int *p = bp;
        for(int *q = ep - 1;; ++p, --q) {
            for(; *p < qv && p < ep; ++p) ;
            for(; *q > qv && q >= bp; --q) ;
            if(p > q)
                break;
            SWAP(*p, *q, t)
        }
        quick_sort(bp, p);
        quick_sort(p + 1, ep);
    } else {
        insert_sort(bp, ep);
    }
}

static void insert_sort(int *bp, int *ep)
{
    int tmp;
    for(int *p = bp + 1, *q; p < ep; ++p) {
        tmp = *p;
        q = p - 1;
        for(; tmp < *q && q >= bp; --q)
            *(q + 1) = *q;
        *(q + 1) = tmp;
    }
}
#endif

#ifdef COLL_PRINT
static void print_coll(int *v, int l)
{
    for(int i = 0; i < l;) {
        cout << v[i] << '/t';
        if(!(++i % 10))
            cout << endl;
    }
}
#endif

發佈了43 篇原創文章 · 獲贊 12 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章