只有一重循环的排序——侏儒排序(Gnome Sort)
侏儒排序:從頭(i=0)開始遍歷元素,如果當前元素比前一個元素大(array[i]>array[i-1]),就把它跟前一個元素互換(Swap(a[i],a[i-1]))并繼續檢查它(i--),否則檢查下一個元素(i++)。當i=length時結束排序。
? ? ? ? 該排序的神奇之處是只有一重循環,而且代碼簡單。但是一重循環不代表時間復雜度更小,它的時間復雜度依然是O(n^2),原因就在于代碼里的i--起到了和二次循環相同的效果。
優點:
1. 最好情況下時間復雜度低——O(n),一個循環跑下來始終i++,非常順利。
2. 排序穩定,只交換相鄰元素的排序都是穩定的。
3. 額外空間使用少,只需要i(記錄進度)和t(交換緩存)。如果比較元素是數字,t都能省掉(不使用臨時變量交換兩個數字)。
缺點:
效率低。我們對比侏儒排序和直接插入排序。會發現這二者的排序思想一模一樣,但是插入排序有2處優化是侏儒排序沒做到的:
a. 插入排序遇到不匹配位置的新元素時,把前面的元素挨個后移,然后把新元素直接插入到合適位置(如果位置移動k位,則賦值k+1次)。而侏儒排序是把新元素逐個和前一個元素作交換,一路換位到合適位置,這是典型的冒泡做法(如果位置移動k位,則賦值3*k次)。
b. 當一個元素好不容易從第10位冒泡到第1位的時候,那么此時前10位一定是有序序列。插入排序會直接從第11位繼續處理,而侏儒排序只能從第2位繼續處理,因為它不知道上個元素是從哪個位置走到第1位的,只好多走冤枉路。
下面是C#代碼:
void GnomeSort(List<int> a) {int i = 0;while (i < a.Count){if (i == 0 || a[i - 1] <= a[i]){i++;}else{int t = a[i];a[i] = a[i - 1];a[i - 1] = t;i--;}} }? ? ? ? 當然,我們可以通過打補丁的方式來優化它,不過如果這么做了,我們干嘛不直接使用直接插入排序呢?作為直接插入排序的劣質版,它基本上沒有實用價值,但是通過研究它,我們就能知道為什么直接插入排序能在這一眾O(n^2)排序中脫穎而出了。
轉載于:https://www.cnblogs.com/9-de/p/6600640.html
總結
以上是生活随笔為你收集整理的只有一重循环的排序——侏儒排序(Gnome Sort)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图片实现水平垂直居中的方法
- 下一篇: [QT学习]-调色板|选择文件