梳排序(CombSort)思想與實現
梳排序也屬於簡單的排序演算法,也是一種不穩定的排序方法。在講述梳排序的思想之前,先介紹一下與該排序有關的一個關鍵常量:遞減率;該常量為固定值:1.3。該常量是由原作者Wlodzimierz Dobosiewicz以隨機數做實驗得到的,對於此大可不必糾結,直接用就行。
(1) 梳排序的思想
梳排序的思想就是:最開始的時候先定義一個步長,該步長為陣列的長度除以1.3(注意:直接用整型除即可,例如陣列長度為5,則開始的步長為5/1.3=3),然後從第0個元素開始,跟距離當前元素為步長大小的元素進行比較(例如,開始步長為3,所以第0個元素跟第3個元素進行比較),若前者大於後者就進行交換,否則繼續往後進行比較,直到比較到最後一個元素為止;完成前面的操作後,第一步就算完成了,接下來從第二步開始,將第一步的步長除以1.3(第一步的例子中步長為3,故第二步的步長為3/1.3=2
所以,從上述的思想中,我們知道:遞減率其實就是所要比較的兩個元素的間距的遞減率。為了更好地理解該演算法的思想,我們來看以下圖片:
從上圖可以知道,原始陣列為: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。
第八步;第七步的步長為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.所有從根節點到外部節點的路徑上都有