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、等系列專題。原創不易,更新較慢,多多包涵。希望與你共同成長。我們下期再見啦,拜了個拜~