世界上最漂亮的排序算法!

直奔主題,世界上「最漂亮」的排序算法。前端

void stooge_sort(int arr[], int i, int j){
         if (arr[i]>arr[j]) swap(arr[i], arr[j]);
         if (i+1>=j) return;

         int k=(j-i+1)/3;
         stooge_sort(arr, i, j-k);
         stooge_sort(arr, i+k, j);
         stooge_sort(arr, i, j-k);
}

《算法導論》習題中的「完美排序」,由Howard、Fine等幾個教授提出,之因此稱爲「完美排序」,是由於其代碼實現,優雅、工整、漂亮。面試

代碼不是很好理解,一步步講解下思路。
世界上最漂亮的排序算法!
首先,排序傳入的參數是待排序的數組arr[i, j];
世界上最漂亮的排序算法!算法

第一步:比較i與j位置的元素,根據排序規則決定是否進行置換。
畫外音:本栗子,假設排序規則是從小到大。
置換完成後,判斷排序是否結束,當i和j相鄰時,排序結束。後端

世界上最漂亮的排序算法!
第二步:將arr[i, j]三等分;
畫外音:總元素個數是j-i+1。數組

世界上最漂亮的排序算法!
第三步:遞歸arr的前2/3半區。
世界上最漂亮的排序算法!架構

第四步:遞歸arr的後2/3半區。ide

世界上最漂亮的排序算法!
第五步:遞歸arr的前2/3半區。code

排序結束。blog

神奇不神奇!!!

再看一遍,印象深入不?排序

void stooge_sort(int arr[], int i, int j){
         if (arr[i]>arr[j]) swap(arr[i], arr[j]); // 比較
         if (i+1>=j) return; // 是否結束

         int k=(j-i+1)/3; // 三等分
         stooge_sort(arr, i, j-k); // 前2/3半區
         stooge_sort(arr, i+k, j); // 後2/3半區
         stooge_sort(arr, i, j-k); // 前2/3半區
}

然並卵,除了代碼好看,完美排序毛用沒有,由於它是一個挺慢的算法。

由代碼很容易看出來:
(1)當只有1個元素時,完美排序的時間也是1;
(2)當有n個元素時,完美排序由一個常數計算,加上三次遞歸,每次遞歸數據量爲(2/3)*n;

即,其時間複雜度遞歸式爲:
T(1) = 1;
T(n) = 3T(2/3n) + 1;

使用《搞定全部時間複雜度計算》中的遞歸式計算方法,最終獲得,完美排序的時間複雜度是O(n^2.7),比O(n^2)的排序都要慢。

完美排序的排序證實,不在文章中展開。從代碼直觀能感覺到,經過swap和三次遞歸,趨勢上,小的元素會往前端走,大的元素會日後端走,直至完成排序。
畫外音:快速排序的過程是partition+兩次遞歸,也是小的元素往前端走,大的元素日後端走,直至完成排序。

但願這一分鐘,你們有收穫。
世界上最漂亮的排序算法!
架構師之路-分享可落地的技術文章

推薦閱讀:
《TopK與快速排序深度解析》
《搞定全部時間複雜度計算》
《拜託,面試別再問我基數排序了!》
《拜託,面試別再問我計數排序了!》
《拜託,面試別再問我桶排序了!》

做業:在本身的電腦上,實現6行的完美排序,從此面試手寫排序再也不是問題。

相關文章
相關標籤/搜索