1. 程式人生 > >梳排序(CombSort)思想與實現

梳排序(CombSort)思想與實現

  梳排序也屬於簡單的排序演算法,也是一種不穩定的排序方法。在講述梳排序的思想之前,先介紹一下與該排序有關的一個關鍵常量:遞減率;該常量為固定值:1.3。該常量是由原作者Wlodzimierz Dobosiewicz以隨機數做實驗得到的,對於此大可不必糾結,直接用就行。

(1) 梳排序的思想

  梳排序的思想就是:最開始的時候先定義一個步長,該步長為陣列的長度除以1.3(注意:直接用整型除即可,例如陣列長度為5,則開始的步長為5/1.3=3),然後從第0個元素開始,跟距離當前元素為步長大小的元素進行比較(例如,開始步長為3,所以第0個元素跟第3個元素進行比較),若前者大於後者就進行交換,否則繼續往後進行比較,直到比較到最後一個元素為止;完成前面的操作後,第一步就算完成了,接下來從第二步開始,將第一步的步長除以1.3(第一步的例子中步長為3,故第二步的步長為3/1.3=2

)後得到新的步長,之後參照第一步的做法進行比較,直到比較到最後一個元素為止;接下來講述一下約束條件,當步長小於1的時候,不再進行比較操作。此外,稍微提一下,該例子以排升序為例,排降序與其類似,讀者參照後可自行編寫。

  所以,從上述的思想中,我們知道:遞減率其實就是所要比較的兩個元素的間距的遞減率為了更好地理解該演算法的思想,我們來看以下圖片:


從上圖可以知道,原始陣列為:41  11  7  16  25  4  23  32  31  22  9  1  22  3  7  31  6  10,以排升序為例,接下來進行分步操作。

  第一步:陣列長度為19,故第一步的步長為19/1.3=14。故第0個元素41與第14個元素3進行比較,41大於3,進行交換;同理,第1個元素11與第15個元素7進行比較,11大於7,進行交換;以此類推,比較到最後一個元素後,此時陣列變成:3  7  18  6  10  25  4  23  32  31  22  9  1  22  41  11  31  7  16

  第二步:第一步的步長為14,故第二步的步長為14/1.3=10。故第0個元素3與第10個元素22進行比較,3小於10,不進行交換;同理,第1個元素7與第11個元素9進行比較,7小於9,不進行交換;以此類推,比較到最後一個元素後,此時陣列變成:3  7  1  6  10  11  4  7  16  31  22  9  18  22  41  25  31  23  32

  第三步:第二步的步長為10,故第三步的步長為10/1.3=7。故第0個元素3與第7個元素7進行比較,3小於7,不進行交換;同理,第1個元素7與第8個元素16進行比較,7小於9,不進行交換;以此類推,比較到最後一個元素後,此時陣列變成:3  7  1  6  9  11  4  7  16  31  22  10  18  22  41  25  31  23  32


  第四步:第三步的步長為10,故第四步的步長為10/1.3=7。故第0個元素3與第7個元素7進行比較,3小於7,不進行交換;同理,第1個元素7與第8個元素16進行比較,7小於9,不進行交換;以此類推,比較到最後一個元素後,此時陣列變成:3  7  1  6  9  11  4  7  16  31  22  10  18  22  41  25  31  23  32

  第五步;第四步的步長為7,故第五步的步長為7/1.3=5。故第0個元素3與第5個元素11進行比較,3小於11,不進行交換;同理,第1個元素7與第6個元素4進行比較,7大於4,進行交換;以此類推,比較到最後一個元素後,此時陣列變成:3  4  1  6  9  11  7  7  16  31  22  10  18  22  41  25  31  23  32

  第六步;第五步的步長為5,故第六步的步長為5/1.3=3。故第0個元素3與第3個元素6進行比較,3小於6,不進行交換;同理,第1個元素4與第4個元素9進行比較,4大於9,不進行交換;以此類推,比較到最後一個元素後,此時陣列變成:3  4  1  6  7  10  7  9  11  18  22  16  31  22  23  25  31  41  32   第七步;第六步的步長為3,故第七步的步長為3/1.3=2。故第0個元素3與第2個元素1進行比較,3大於1,進行交換;同理,第1個元素4與第3個元素6進行比較,4小於6,不進行交換;以此類推,比較到最後一個元素後,此時陣列變成:1  4  3  6  7  9  7  10  11  16  22  18  23  22  31  25  31  41  32
  第八步;第七步的步長為2,故第八步的步長為2/1.3=1。故第0個元素1與第1個元素4進行比較,1大於4,不進行交換;同理,第1個元素4與第2個元素3進行比較,4大於3,進行交換;以此類推,比較到最後一個元素後,此時陣列變成:1  3  4  6  7  7  9  10  11  16  18  22  22  23  25  25  31  31  32  41

(2) 梳排序的實現

  本次排序演算法採用C++模版程式設計來實現。

#include <iostream>
#include <iterator>
#include <iomanip>

using namespace std;


template<class T,size_t N>
void PrintArr(T (&arr)[N])
{
    copy(arr,arr + N,ostream_iterator<T>(cout," "));
    cout << endl;
}


template<class T,size_t N>
void CombSort(T (&arr)[N])
{
    size_t gap(N);
    while(gap > 0) {
        gap /= 1.3;
        for(size_t i = 0; i+gap < N; i++) {
            if(arr[i] > arr[i+gap]) {
                swap(arr[i],arr[i+gap]);
            }
        }
        PrintArr(arr);
    }
}

template<class SortFunc>
void Test(SortFunc sort)
{
    int arr[]= {41,11,18,7,16,25,4,23,32,31,22,9,1,22,3,7,31,6,10};
    PrintArr(arr);
    sort(arr);
    cout << "The final:" << endl;
    PrintArr(arr);
}
原始陣列為:41  11  7  16  25  4  23  32  31  22  9  1  22  3  7  31  6  10

程式執行結果為:1  3  4  6  7  7  9  10  11  16  18  22  22  23  25  25  31  31  32  41

相關推薦

排序CombSort思想實現

  梳排序也屬於簡單的排序演算法,也是一種不穩定的排序方法。在講述梳排序的思想之前,先介紹一下與該排序有關的一個關鍵常量:遞減率;該常量為固定值:1.3。該常量是由原作者Wlodzimierz Do

基數排序RadixSort思想實現

  基數排序屬於高階的排序方法,該排序演算法是在“桶排序”的基礎上所進行的改進,讀者若是想了解“桶排序”思想,可以點選這裡。接下來介紹一下基數排序的思想。 (1) 基數排序的思想   基數排序的思想就

插入排序InsertSort思想實現

  在介紹插入排序的思想之前,說一下插入排序的一個重要的優點:插入排序只有在需要排序時才會排序。該演算法的時間複雜度為:O(n^2),接下來我們來了解一下該排序的思想。 (1)插入排序的思想   插入

選擇排序SelectSort思想實現

  選擇排序屬於相對來說比較簡單的排序方法,時間複雜度為:O(n^2)。 (1) 選擇排序的思想   選擇排序的思想就是:選擇排序的本意在於每次選擇出最小或者最大的元素,將其放在陣列的前面,從而使得陣

歸併排序MergeSort思想實現

  歸併排序屬於高階的排序方法,在介紹歸併排序的思想之前,先講述一種採用比較方式的排序方法。假設有兩個已經排好序的陣列arr1[ ],arr2[ ],且均是升序或者降序,那麼可以進行以下操作:以升序為

排序BucketSort思想實現

  桶排序屬於簡單而且易於理解的排序演算法,接下來介紹一下該演算法的思想。 (1) 桶排序的思想   桶排序的思想就是:首先遍歷一遍陣列,找出陣列中值最大的元素,假設最大的元素為Max;然後定義Max

快速排序Quicksort的Javascript實現

簡單 fun 遍歷數組 floor 演示 ont -s urn 元素 日本程序員norahiko,寫了一個排序算法的動畫演示,非常有趣。 這個周末,我就用它當做教材,好好學習了一下各種排序算法。 排序算法(Sorting algorithm)是計算機科學最古老、最基

kaggle入門項目:Titanic存亡預測驗證實現

tps 多參數 name 出了 運算 處理 defaults purpose sof 原kaggle比賽地址:https://www.kaggle.com/c/titanic 原kernel地址:A Data Science Framework: To Achieve 99

離散傅立葉變換DFT和快速傅立葉變換FFT原理實現

目錄 1、影象變換 2、離散傅立葉變換(Discrete Fourier Transform) 3、DFT性質 4、DFT與數字影象處理 5、FFT-快速傅立葉變換 6、DFT與FFT的演算法實現 1. 影象變換 — —數學領域中有很多種變換,如傅立葉變換、拉普拉斯變

八大排序演算法實戰:思想實現

摘要:   所謂排序,就是根據排序碼的遞增或者遞減順序把資料元素依次排列起來,使一組任意排列的元素變為一組按其排序碼線性有序的元素。本文將介紹八種最為經典常用的內部排序演算法的基本思想與實現,包括插入排序(直接插入排序,希爾排序)、選擇排序(直接選擇排序,堆排

平衡二叉樹AVL圖解實現

平衡二叉樹(Balanced BinaryTree)又被稱為AVL樹。它具有以下性質:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。 平衡二叉樹一般是一個有序樹,它具有二叉樹的所有性質,其遍歷操作和二叉樹的遍歷操作相同。

java資料結構演算法之棧Stack設計實現

關聯文章:   本篇是java資料結構與演算法的第4篇,從本篇開始我們將來了解棧的設計與實現,以下是本篇的相關知識點: 棧的抽象資料型別   棧是一種用於儲存資料的簡單資料結構,有點類似連結串列或者順序表(統稱線性表),棧與線性表的最大區別是

java實現歸併排序思想實現

歸併排序歸併排序是採用分治法的一個非常典型的應用。歸併排序的思想就是先遞迴分解陣列,再合併陣列。將陣列分解最小之後,然後合併兩個有序陣列,基本思路是比較兩個陣列的最前面的數,誰小就先取誰,取了後相應的指標就往後移一位。然後再比較,直至一個數組為空,最後把另一個數組的剩餘部分複

Java排序算法分析實現:快排、冒泡排序、選擇排序、插入排序、歸並排序

第一個元素 spa insert 循環 冒泡排序 author 高級算法 ins -s 一、概述:   上篇博客介紹了常見簡單算法:冒泡排序、選擇排序和插入排序。本文介紹高級排序算法:快速排序和歸並排序。在開始介紹算法之前,首先介紹高級算法所需要的基礎知識:劃分、遞歸,並順

算法——python實現快速排序二分法思想

append exc microsoft 部分 input temp style 數字 快速排序 實現思路   將所需要的數字存入一個列表中 首先,設置將最左側的那個數設置為基準數,在列表中索引為0 然後設置兩個移動位(用於比較),分別為最左邊和最右邊 然後最右邊那位向左

Java排序演算法(三)--歸併排序MergeSort遞迴非遞迴的實現

歸併有遞迴和非遞迴兩種。 歸併的思想是: 1.將原陣列首先進行兩個元素為一組的排序,然後合併為四個一組,八個一組,直至合併整個陣列; 2.合併兩個子陣列的時候,需要藉助一個臨時陣列,用來存放當前的

理解機器學習和深度學習的核心思想實現思路 入門總結[圖文 + 詳細思路]

本文講解涉及到的核心思想: 機器學習與深度學習: 1:線性迴歸問題。 2:優化搜尋時,步長選取的重要性。 3:為什麼神經網路可以擬合任意的曲線函式。 4:影象識別網路中,為什麼淺層網路只能識別出一些簡單的線,面,隨著網路的加深可以識別出十分複雜的圖案。 1:線性迴歸

Java排序演算法分析實現:快排、氣泡排序、選擇排序、插入排序、歸併排序

轉載  https://www.cnblogs.com/bjh1117/p/8335628.html   一、概述:   本文給出常見的幾種排序演算法的原理以及java實現,包括常見的簡單排序和高階排序演算法,以及其他常用的演算法知識。   簡單排序:氣泡排序、選擇排序、

求斐波那契數列的第n項思想實現

題目描述大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項。n<=39首先在這裡先講講這個什麼是斐波那契數列,斐波那契數列的第一項是0,第二項是1然後從第三項開始每項等於前兩項的和.f(n) = f(n - 1) + f(n - 2)如f(0)

紅黑樹演算法的思想實現

紅黑樹 是一顆二叉搜尋樹:樹中每一個節點不是黑色就是紅色。可以把一顆紅黑樹視為一顆擴充二叉樹,用外部節點表示空指標。。。 有如下特性: 1.根節點和所有外部節點的顏色是黑色。 2.從根節點到外部節點的途中沒有連續兩個節點的顏色是紅色。 3.所有從根節點到外部節點的路徑上都有