算法與數據結構(十三) 冒泡排序、插入排序、希爾排序、選擇排序(Swift3.0版)

本篇博客中的代碼實現依然採用Swift3.0來實現。在前幾篇博客連續的介紹了關於查找的相關內容, 大約包括線性數據結構的順序查找、折半查找、插值查找、Fibonacci查找,還包括數結構的二叉排序樹以及平衡二叉樹的構建與查找,而後還聊了哈希表的構建與查找。接下來的幾篇博客中咱們就集中的聊一下常見的集中排序方式,並並給出相應的時間複雜度。本篇博客咱們將會詳細的介紹冒泡排序、插入排序、希爾排序以及選擇排序,下篇博客將繼續介紹堆排序、歸併排序以及快速排序的相關內容。固然上述內容的代碼實現咱們依然採用Swift面向對象語言來實現。git

本篇博客的思路與以往博客的思路一直,先分析每種排序的規則,而後給出原理示意圖,最後根據示意圖給出相應的代碼實現。編程這東西,只要是思路清晰,給出相應的代碼實現並不困難,本篇是使用Swift語言來實現的,若是你對Swift語言不熟悉,你能夠選擇其餘你熟悉的語言來實現。雖然語言不一樣,可是思路和方法都是同樣的。廢話少說,開始今天博客的主題。github

 

1、排序協議的定義算法

在博客的開頭的,咱們先給出排序協議的定義。由於咱們本篇博客含有多種排序方式,爲了使每種排序方法對外調用方式一致,咱們須要定義一個排序的相關協議。全部排序的相關類都必須遵循該協議,讓此協議來定義具體的排序類對外的調用方式。編程

下方的SortType協議就是咱們定義的排序類型的協議。其中的sort()方法是遵循該協議的類必需要實現的方法。sort()函數的參數是一個含有Int類型的數組,該數組就是要排序的數組。該方法的返回值是已經被排好序的數組。具體代碼以下所示。數組

  

 

 

 2、冒泡排序數據結構

接下來咱們來聊一下冒泡排序,冒泡排序就像其名字同樣,仍是比較生動的。在冒泡排序過程當中會將數組分紅兩部分,一部分是已經有序的數列,一部分是無序的數列。無序數列中不斷的將其中最小的值往有序序列中冒泡,泡冒完後,咱們的序列就建立好了。本部分,咱們將要給出冒泡排序的示意圖,已經相應的代碼實現。函數

 

一、冒泡排序示意圖測試

下方就是第一輪冒泡的具體過程,咱們要對[62, 88, 58, 47, 62, 35, 73, 51, 99, 37, 93]序列進行冒泡排序。通過第一輪的冒泡後,該序列中最小的值35被冒到了數列的最前方。由於冒泡的過程是挨個比較已經交換的過程。元素狀態咱們的泡中是93,93與前一個值37進行比較,發現37要小於93,因此將泡中的值改爲37,並往前移動。緊接着37在與前面的99比較,發現泡中的值要小,此刻不更新泡中的值並往前移動一個格。以此類推,無序序列中最小的值就會被冒到序列的起始位置。spa

每輪冒泡都會從無序序列中冒出那個最小的值,因此通過n(數列有n個值)次冒泡後,咱們的數列就是有序的了。冒泡過程當中的比較與交換的具體步驟以下所示:對象

  

2.代碼實現

根據上述示意圖,咱們很容易給出下方的代碼。下方就是冒泡排序的代碼,BubbleSort這個類就是冒泡排序所對應的類,此類爲了統一對外的調用方式,因此必需要遵循咱們上一部分所定義的SortType協議。

說白了,冒泡的過程就是不斷比較和交換的過程,若是前一個值比後一個值要大,那麼就要進行交換了

  

 

三、運行結果

下方代碼就是上述BubbleSort類所運行的具體結果。排序結果中詳細的打印了冒泡排序在每一輪冒泡中每一步要作的事情,具體以下所示。

  

  

 

 

3、插入排序

插入排序算是比較好理解的排序方式,插入排序也是將要排序的數列分爲兩部分,前半部分是已經排好序的,後半部分則是無序的。插入排序中的插入是指「取出無序數列中第一個值,插入到有序數列中相應的位置」。其實這個插入過程也是不斷比較和交換的過程。

 

一、插入排序示意圖

下方就是插入排序的示意圖,紅色部分是有序數列,而綠色部分是無序數列。每一輪插入都會取出無序數列中的第一個元素插入到有序數列中,這個插入的過程其實就是一個比較交換的過程,若是要插入的值比前面的值要小,就要交換,直到不能交換爲止。下方就是插入排序的過程。具體以下所示:

  

二、代碼實現

有了上述的示意圖,給出相應的代碼實現並不困難。代碼的核心思想就是經過循序不斷從無序數列中取出值,而後循環遍歷有序數列尋找合適的插入點。在下方中有兩個循環嵌套,外層循環負責不斷從無序序列中取值,而後經過內層循環將外層循環取出的值插入到有序數列中相應的位置,具體以下代碼所示:

  

 

三、運行結果

下方是運行結果的截圖,該運行結果其實就是插入排序的詳細過程。每一輪插入的過程就是有序序列增長,無序序列減小的過程。下方就是插入過程的詳細信息。

  

 

 

4、希爾排序

由於這個排序是一個叫希爾的人發明的,因此就叫希爾排序了。其實希爾排序是插入排序的升級版, 希爾排序根據其排序的特色又叫作縮小增量排序。希爾排序的大致步驟就是先將無序序列按照必定的步長(增量)分爲幾組,分別將這幾組中的數據經過插入排序的方式將其進行排序。而後縮小步長(增量)分組,而後將組內的數據再次進行排序。知道增量爲1位置。通過上述這些步驟,咱們的序列就是有序的了。其實上述的插入排序就是增量爲1的希爾排序,下方會給出相應的示意圖以及代碼實現。

 

1.希爾排序示意圖

下方就是希爾排序的詳細步驟,接下來咱們將會對每一步進行詳細的解說。以下所示:

  • (1)、首先按照增量進行分組,由於咱們要排序的數列有11個,增量初始值是 step = 11 / 2 = 5。也就是按照增量爲5的步長對數組進行分組。在下方第一步中就是按照增量爲5的方式進行分組的。咱們將爲一組的元素使用直線進行相連,分完組後,咱們就將組內中的元素進行插入排序。
  • (2)、將上一步使用的 增量進行縮小,也就是本步驟的 step = 5 / 2 = 2。 本部分,就要按照2的增量將上一步排序後的數組進行分組,而後再次將每一個組內的數據進行插入排序。
  • (3)、 再次縮小增量,此刻 step = 2 / 2 = 1, 當增量爲1時,其實就是咱們上一部分的插入排序。將整個數組進行插入排序,而後咱們的數組就是有序的了。

具體示意圖以下所示:

  

 

二、希爾排序的代碼實現

根據上述的步驟,而後再結合着插入排序的代碼,給出希爾排序相應的代碼並不困難。就是將插入排序的步長從1修改爲咱們每次生成的步長便可,每次增量排序完畢後,咱們要對增量按照相應的規則進行縮小便可。下方就是希爾排序的代碼實現。

在下方代碼中,最外層循環負責增量的生成和縮減,裏邊的雙重循環就是咱們以前咱們插入排序的代碼,不步長要使用咱們希爾排序生成的step,具體代碼以下所示:

  

 

三、運行結果

下方就是Shell排序的運行結果,從下方結果中咱們不難看出增量是逐漸減少的。下方的輸出結果結合着本部分第一部分的示意圖看更爲直觀一些。

  

 

 5、選擇排序

接下來來聊聊選擇排序,選擇排序也是比較好理解的。在選擇排序過程當中,數組仍然被分做有序和無序兩部分。而選擇排序中的「選擇」是指不斷從無序序列中選擇最小的值放入到有序序列的最後的位置,換句話說就是從現有的無序序列中找出那個最小的值,而後與無序序列的第一個值進行交換,而後縮小無序序列的範圍便可。由於有序序列的最後一個值與無序序列的第一個值緊挨着,交換後,這個無序序列中的第一個值就成了有序序列的最後一個值。重複這個選擇的過程,咱們的數組就會變得有序。下方將會給出詳細的示意圖以及相應的代碼實現。

 

1.選擇排序示意圖 

下方就是簡單選擇排序的部分步驟,只須要重複下方的步驟就能夠經過選擇排序將咱們的數組變成有序的序列。下方是對下方步驟的詳細介紹:

  • 初識狀態下,咱們整個數組就是無序的,從整個數組中咱們找到了最小的元素35,其下標爲5。而後將35與無序序列第一個元素62進行交換。交換後,有序序列中就有了一個值:35,而無序序列中就少了一個值:35。無序序列中的第一個值也就是變成了88。
  • 再次從無序序列中選擇那個最小的值。因而乎咱們又找到了37,而後讓37與88進行交換。有序序列就成了 {35,37}
  • 再次從無序序列中選擇最小的那個值,通過查找咱們找到了47,而後將47與58進行交換。此刻有序序列就成了 {35, 37, 47}
  • 重複的從無序序列中選擇最小的值進行交換......

  

 

2.選擇排序具體代碼實現

有了上述選擇的示意圖,根據思路敲代碼。下方就是選擇排序的具體代碼實現。代碼實現起來仍是比較簡單的,就是經過一個循環,不斷的從無序序列中選出那個最小的值與無序序列中的第一個值進行交換便可。下方第一個框中就是從無序序列中查找最小的那個值的代碼,第二個框就是交換的過程。以下所示:

  

 

三、運行結果

與上幾個排序同樣,咱們輸出的運行結果就是選擇排序的詳細的過程。下方就是選擇排序的詳細過程,以下所示:

  

 

6、測試用例

在博客要結尾的部分,咱們仍然會給出本篇博客所使用的測試用例。下方就是本篇博客所使用的測試用例。上述的運行結果就是下方咱們測試用例的輸出結果。雖然輸出的結果不一樣,可是咱們用的都是一個測試函數,只是傳入的排序對象不一樣。這也就是咱們在程序的第一部分爲何要給出相應的協議定義的緣由。測試用例以下所示:

  

 

本篇博客所涉及的全部代碼都會在github上進行分享,下方是分享地址。後面會繼續更新其餘排序算法。

github代碼分享地址: https://github.com/lizelu/DataStruct-Swift/tree/master/AllKindsOfSort 

相關文章
相關標籤/搜索