1. 程式人生 > >Go語言冒泡、選擇、插入、快速排序實戰淺析

Go語言冒泡、選擇、插入、快速排序實戰淺析

Hello,各位小夥伴大家好,我是小棧君,今天為大家帶來的分享是關於go語言中的排序實戰淺析。

我們就實際操作關於go的氣泡排序、選擇排序、插入排序和快速排序四種方式的理論和實戰進行分享,希望能夠為大家在學習的路上帶來點啟發和經驗。

排序在我們平時的程式設計工作中時常可以見到,以按照不同的規則進行排序返回,以便於滿足業務的需要。瞭解和學會編寫排序也算是我們在學習程式語言中的演算法前進的一小步了,所以呢,小夥伴一起加油吧~

排序的含義

百度百科中有明確的闡述,排序是計算機內經常進行的一種操作,其目的是將一組“無序”的記錄序列調整為“有序”的記錄序列。分內部排序和外部排序,若整個排序過程不需要訪問外存便能完成,則稱此類排序問題為內部排序。

反之,若參加排序的記錄數量很大,整個序列的排序過程不可能在記憶體中完成,則稱此類排序問題為外部排序。內部排序的過程是一個逐步擴大記錄的有序序列長度的過程。

氣泡排序

已知一組無序資料a[1]、a[2]、……a[n],需將其按升序排列。首先比較a[1]與a[2]的值,若a[1]大於a[2]則交換兩者的值,否則不變。再比較a[2]與a[3]的值,若a[2]大於a[3]則交換兩者的值,否則不變。

再比較a[3]與a[4],以此類推,最後比較a[n-1]與a[n]的值。這樣處理一輪後,a[n]的值一定是這組資料中最大的。再對a[1]~a[n-1]以相同方法處理一輪,則a[n-1]的值一定是a[1]~a[n-1]中最大的。

再對a[1]~a[n-2]以相同方法處理一輪,以此類推。共處理n-1輪後a[1]、a[2]、……a[n]就以升序排列了。降序排列與升序排列相類似,若a[1]小於a[2]則交換兩者的值,否則不變,後面以此類推。

總的來講,每一輪排序後最大(或最小)的數將移動到資料序列的最後,理論上總共要進行n(n-1)/2次交換。

它所具有的優點就是穩定。但是缺點也是非常明顯,就是慢,每次只能移動相鄰兩個資料。

所以我們用一個例子形象的說明一下氣泡排序的原理,針對於上述可能是對初學者理解起來有點抽象。

以上是一個數組中三個數字,我們先看一下黑色線條,先是第一個數字2和第二個數字5做比較,如果說2比5大的話就交換兩個值的位置。
然後是2和1做比較,如果2比1大,相同的交換兩個數字的位置,所以我們得到了1、5、2這樣的陣列,然後又開始進行5和2的對比,5比2大,然後交換位置,至此資料遍歷完畢。

得到了1、2、5這樣的陣列。當然我們也可以制定規則,數字大的冒泡,最終得到的結果就是5、2、1這樣的陣列。所以我們實現的方式如下圖所示:

選擇排序

每一趟從待排序的資料元素中選出最小(或最大)的一個元素,順序放在已排好序的數列的最後,直到全部待排序的資料元素排完。

也就是在一個數組中我們要依次選擇最小的或是最大的數來進行數組裡面的值交換,最後得到最終排序好的陣列。

這樣做的優點就是就是知道執行的次數是n-1次,但是缺點也很明顯就是比較次數較多。

用圖形表示如圖所示:

我們先進行5和2對比,然後和1對比,找到最小的1,然後進行交換位置,此時無序的陣列剩下5和2,然後找到最小的2,交換位置。最後將最大的5放入最後的位置。這樣就完成了最簡單的一個選擇排序。

具體程式碼如下:

插入排序

已知一組升序排列資料a[1]、a[2]、……a[n],一組無序資料b[1]、b[2]、……b[m],需將二者合併成一個升序數列。首先比較b[1]與a[1]的值,若b[1]大於a[1],則跳過。

比較b[1]與a[2]的值,若b[1]仍然大於a[2],則繼續跳過,直到b[1]小於a陣列中某一資料a[x],則將a[x]~a[n]分別向後移動一位,將b[1]插入到原來a[x]的位置這就完成了b[1]的插入。

b[2]~b[m]用相同方法插入。(若無陣列a,可將b[1]當作n=1的陣列a)它所具有的優點是穩定和快。

但是比較次數不一定,比較次數越多,插入點後的資料移動越多,特別是當資料總量龐大的時候,但用連結串列可以解決這個問題。

如果目標是把n個元素的序列升序排列,那麼採用插入排序存在最好情況和最壞情況。最好情況就是,序列已經是升序排列了,在這種情況下,需要進行的比較操作需(n-1)次即可。

最壞情況就是,序列是降序排列,那麼此時需要進行的比較共有n(n-1)/2次。插入排序的賦值操作是比較操作的次數加上 (n-1)次。平均來說插入排序演算法的時間複雜度為O(n^2)。

因而,插入排序不適合對於資料量比較大的排序應用。但是,如果需要排序的資料量很小為量級小於千,那麼插入排序還是一個不錯的選擇。

所以我們用影象的形式描述的話,原始陣列是一個需要進行排序的陣列,我們可以將陣列的第一個元素當成一個單獨且有序的陣列A,然後剩下的元素形成新的陣列C依次進行對比。

如果發現C中有元素比A中大就按照指定的規則插入元素的左側(或右側)。直至對比到C陣列中的最後一個。此時A中的元素都是有序的陣列。

程式碼如圖所示:

快速排序

快速排序是大家已知的常用排序演算法中最快的排序方法。已知一組無序資料a[1]、a[2]、……a[n],需將其按升序排列。

首先任取資料a[x]作為基準。比較a[x]與其它資料並排序,使a[x]排在資料的第k位,並且使a[1]~a[k-1]中的每一個數據<a[x],a[k+1]~a[n]中的每一個數據>a[x]。

然後採用分治的策略分別對a[1]~a[k-1]和a[k+1]~a[n]兩組資料進行快速排序。

它所具有的優點屬於極快,資料移動少。當然存在的隱患就是不穩定。

所以結合圖片分享可能會更好容易理解一點。在一個無序的陣列中,首先我們確定一個初始值,假定為我們取值為第一個,然後對整個元素進行遍歷,將小於5位置排在左邊,將大於5的排在右邊,此時就分為左右兩個陣營。

然後我們將兩個陣營的元素各自再進行排序,最終就得到了我們排序好的陣列啦。

具體程式碼如下圖所示:

當然,這裡也是可以不用傳左右邊界,我們可以預設為初始值左邊界為0,右邊界為len(array)-1。

好了,今天的分享就到這啦,如果你喜歡我的分享,麻煩你點選一個好看或贊,我是小棧君,不定期分享IT乾貨,包括但不限於區塊鏈、大資料、Python、go、等系列專題。原創不易,更新較慢,多多包涵。希望與你共同成長。我們下期再見啦,拜了個