插入、選擇、冒泡、梳排序性能比較


        雖然標題中的排序算法往往被認為是低效率的算法.但並不意味着這些算法完全沒有可取之處。本次不再探討這些算法的基本原理,僅僅比較算法的性能,並貼出實現這些算法的源代碼:

        還是先肝代碼吧(手動狗頭):

# include"iostream"
# include "vector"
# include "ctime"
# include "cstdlib" 
using namespace std;
void insert_sort(vector<int> & );
void ChooseSort(vector<int> &);
void BubbleSort(vector<int> &);
void CombSort(vector<int> & );

int main()
{
    const int MAX_NUMBER = 3000;//生成的隨機數的個數
    const int MIN_VALUE = 1;   //隨機數值的下界
    const int MAX_VALUE = 20000;//隨機數值的上界
    vector<int> a;
    a.reserve(MAX_NUMBER);//預先分配內存你,預防迭代器的失效。否則內存搬移,迭代器容易失效

    // 采用控制台輸入的方式 
    //int temp;
    //while (cin >> temp)
    //{
    //    a.push_back(temp);
    //    if (cin.get() == '\n') //注意這種用法,用的很多。
    //    {
    //        break;
    //    }
    //}

    //采用隨機數生成法。
    srand((unsigned)time(NULL));//根據時鍾生成不同的種子,保證每次運行程序產生不同的隨機數
    for (int i = 1; i <= MAX_NUMBER; i++)
    {
        int temp;
        temp = (rand() % (MAX_VALUE - MIN_VALUE + 1)) + MIN_VALUE;//生成[MIN_VALUE,MAX_VALUE]之間的整數隨機數
        a.push_back(temp);
    }
    //cout << "The initial order: ";    數據量太大,不適合輸出
    //vector<int>::iterator ia = a.begin();
    //for (; ia != a.end(); ia++)
    //{
    //    cout << *ia << " ";
    //}
    //cout << endl;
    vector<int> b(a);
    vector<int> c(a);
    vector<int> d(a);
    //show the initial order of the vector
    //cout << "The initial order before Sorting : ";
    //vector<int> ::iterator ia = a.begin();
    //for (; ia != a.end(); ia++)
    //{
    //cout << *ia << " ";
    //}
    //cout << endl;
    // 插入排序測試
    clock_t start, finish;
    double runtime;
    start = clock();
    insert_sort(a);
    finish = clock();
    runtime = (double)(finish - start) / CLOCKS_PER_SEC;
    cout << "The time of Insert Sort algorithm is:" << runtime << "s" << endl;
    // 選擇排序測試
    start = clock();
    ChooseSort(b);
    finish = clock();
    runtime = (double)(finish - start) / CLOCKS_PER_SEC;
    cout << "The time of Choose Sort algorithm is:" << runtime << "s" << endl;
    // 冒泡排序測試
    start = clock();
    BubbleSort(c);
    finish = clock();
    runtime = (double)(finish - start) / CLOCKS_PER_SEC;
    cout << "The time of Bubble Sort algorithm is:" << runtime << "s" << endl;
    // 梳排序測試
    start = clock();
    CombSort(d);
    finish = clock();
    runtime = (double)(finish - start) / CLOCKS_PER_SEC;
    cout << "The time of Comb Sort algorithm is:" << runtime << "s" << endl;
    
    //cout << "The new order after Comb Sorting : ";
    //vector<int> ::iterator id = d.begin();
    //for (; id != d.end(); id++)
    //{
    //    cout << *id << " ";
    //}
    //cout << endl;

    system("pause");
    return 0;
}
//插入排序
void insert_sort( vector<int> & sort_a)  ///注意,采用vector<int> 是可以作為參數進行傳遞的,那么是否可以作為返回類型使用呢?
{
    int a_size ,temp;
    a_size = sort_a.size();
    for (int i = 1,j; i < a_size; i++)//注意,將j放在這里聲明,不要放在下一個循環中聲明,否則會造成多次聲明?(但是作用域沒變,多次聲明應該被禁止,所以沒有多次聲明?)
    {
        temp = sort_a[i];
        for (j = i; (j > 0) && (sort_a[j - 1] > temp); j--)//這里先后順序的差別,導致了數組的越界,
        {   
            sort_a[j] = sort_a[j-1];
        }
        sort_a[j] = temp;
        
    }
    //return sort_a;//說明可以將vector<int> 本身作為函數的返回值使用,但是需要清楚的是:返回的時候,內存實際上發生了局部變量復制,所以是否考慮返回引用???
}
//選擇排序
void ChooseSort(vector<int> & sort_a)
{
    int a_size,MinNum;
    a_size = sort_a.size();
    for (int i = 0, j; i < a_size; i++)
    {
        int Loc = i;
        MinNum = sort_a[i];//本質是隨機迭代器的使用
        //temp = sort_a[i];
        for (j = i+1; j < a_size; j++)
        { 
            if (sort_a[j] < MinNum)
            {
                MinNum = sort_a[j];
                Loc = j;
            }
        }
        //sort_a[i] = MinNum;//用於交換,但是本身自帶的函數可以實現
        //sort_a[Loc] = temp;
        if (i != Loc)
        {
            swap(sort_a[i], sort_a[Loc]);//vector自帶的東西
        }
    }
}
//冒泡排序
void BubbleSort(vector<int> & sort_a)
{
    int a_size;
    a_size = sort_a.size();
    for (int j = 0; j < a_size-1; j++)
    {
        for (int i = 0; i < a_size - 1-j; i++)
        {
            if (sort_a[i]>sort_a[i + 1])
                 swap(sort_a[i], sort_a[i + 1]);
        }
    }
}
//梳排序
void CombSort(vector<int> & sort_a)
{
    int step,j,k;
    step = sort_a.size();
    while ((step = int(step / 1.3)) >0)
    {
        for (j = sort_a.size() - 1; j >= step; j--)
        {
            k = j - step;
            if (sort_a[j] < sort_a[k])
            {
                swap(sort_a[j], sort_a[k]);
            }
        }
    }
}

       補充:由於之前對梳排序未做任何的說明,在此簡要的說明一下梳排序:梳排序的本質仍然是冒泡排序,差異在於,梳排序的冒泡對象並不是相鄰元素,而是距離為step的元素,而step是一個變量(右大變小),即“梳子”間隙逐漸變小。而梳排序迭代的終止條件是:當step變成1,即退化為傳統的冒泡后,執行一次,則得到正確的順序

在此,我們給出上述四種排序的測試結果:

不同排序算法性能比較
  5000 10000 15000 20000
插入 0.839s 3.427 7.716s 13.648s
選擇 0.667s 2.276 5.321s 9.208s
冒泡 2.320s 9.177 20.823s 36.542s
0.016s 0.042 0.057s 0.079s

          上述表格中的(5000,10000,....表示數據規模,程序中隨機生成的隨機數,我們可以看到,測試結果表明:按照速度而言,算法的時間性能上:梳>>選擇>插入>冒泡(>表示優於);(冒泡辣雞實錘(開個玩笑)),即算法性能上,梳排序的性能要遠遠高於其他的方式。我們通過觀察算法執行時間,梳狀排序時間復雜度並不是O(n2),似乎比這個時間復雜度要低,實際上也的確如此。而對於插入,選擇,冒泡而言,盡管時間復雜度都是O(n2),但是畢竟還是有所差異,當數據更莫更大的時候,這種差異將會更加明顯,但是無疑,冒泡排序時間復雜度真的高,冒泡排序的最好,最差,平均時間復雜度都是相同的,都是O(n2)。

疑問:在學習梳排序的時候,見有描述稱其為不穩定的算法,不知為何不穩定,望高手能予指點,謝謝!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM