1. 程式人生 > >五分鐘學會一個高難度演算法:希爾排序

五分鐘學會一個高難度演算法:希爾排序

前言

由於LeetCode上的演算法題很多涉及到一些基礎的資料結構,為了更好的理解後續更新的一些複雜題目的動畫,推出一個新系列 ——-《圖解資料結構》,主要使用動畫來描述常見的資料結構和演算法。本系列包括十大排序、堆、佇列、樹、並查集、圖等等大概幾十篇。

希爾排序

希爾排序,也稱遞減增量排序演算法,是插入排序的一種更高效的改進版本。但希爾排序是非穩定排序演算法。
希爾排序是基於插入排序的以下兩點性質而提出改進方法的:

  • 插入排序在對幾乎已經排好序的資料操作時,效率高,即可以達到線性排序的效率;
  • 但插入排序一般來說是低效的,因為插入排序每次只能將資料移動一位;

希爾排序的基本思想是:先將整個待排序的記錄序列分割成為若干子序列分別進行直接插入排序,待整個序列中的記錄“基本有序”時,再對全體記錄進行依次直接插入排序。

演算法步驟

  1. 選擇一個增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
  2. 按增量序列個數 k,對序列進行 k 趟排序;
  3. 每趟排序,根據對應的增量 ti,將待排序列分割成若干長度為 m 的子序列,分別對各子表進行直接插入排序。僅增量因子為 1 時,整個序列作為一個表來處理,表長度即為整個序列的長度。
    來源:https://github.com/hustcc/JS-Sorting-Algorithm

演算法演示

排序動畫過程解釋

  1. 首先,選擇增量 gap = 10/2 ,縮小增量繼續以 gap = gap/2 的方式
  2. 初始增量為 gap = 10/2 = 5,整個陣列分成了 5 組
  3. 按顏色劃分為【 8 , 3 】,【 9 , 5 】,【 1 , 4 】,【 7 , 6 】,【 2 , 0 】
  4. 對這分開的 5 組分別使用上節所講的插入排序
  5. 結果可以發現,這五組中的相對小元素都被調到前面了
  6. 縮小增量 gap = 5/2 = 2,整個陣列分成了 2 組
  7. 【 3 , 1 , 0 , 9 , 7 】,【 5 , 6 , 8 , 4 , 2 】
  8. 對這分開的 2 組分別使用上節所講的插入排序
  9. 此時整個陣列的有序性是很明顯的
  10. 再縮小增量 gap = 2/2 = 1,整個陣列分成了 1 組
  11. 【 0, 2 , 1 , 4 , 3 , 5 , 7 , 6 , 9 , 0 】
  12. 此時,只需要對以上數列進行簡單的微調,不需要大量的移動操作即可完成整個陣列的排序

程式碼實現

為了更好的讓讀者用自己熟悉的程式語言來理解動畫,筆者將貼出多種程式語言的參考程式碼,程式碼全部來源於網上。

C++程式碼實現

Java程式碼實現

Python程式碼實現

JavaScript程式碼實現


如果你是iOS開發者,可以在GitHub上 https://github.com/MisterBooo/Play-With-Sort-OC 獲取更直觀可除錯執行的原始碼。
你可以關注公眾號 五分鐘學演算法 獲取更多排序內容。