希爾排序——重溫排序(二)

weixin_34321977發表於2018-03-08
1852765-844a62ca0dfcc244.jpg

上篇文章提到,插入排序在待排序列基本有序的時候,效率會好很多。這篇文章介紹的希爾排序,其基本思想就是先讓序列基本有序,然後再進行插入排序。

一、演算法描述

希爾排序先將待排序列進行分組,分別進行插入排序,間隔為 gap 的元素為一組。待各組排序完成後,逐漸縮小 gap 的值,重複分組排序過程,直到 gap 值縮小為1,即對整個序列進行一次插入排序。

gap 一般先取 n / 2 ,然後逐步 gap = gap / 2 ,直到 gap 等於1。

二、圖示舉例

下面來看一個希爾排序的圖示,注意觀察兩個的關鍵字為25的元素,思考一下希爾排序的穩定性。

1852765-d92774862ea5640e.jpg

三、演算法實現

C語言版本程式碼奉上。

void shellSort(int list[], int count) {
    for (int gap = count / 2; gap >= 1; gap /= 2) {
        for (int i = 0; i < gap; ++i) {
            insertSort(list, count, i, gap);
        }
    }
}

void insertSort(int list[], int count, int head, int gap) {
    int temp, i, j;
    for (i = head + gap; i < count; i += gap) {
        temp = list[i];
        for (j = i - gap; j >= head; j -= gap) {
            if (list[j] <= temp) {
                break;
            }
            list[j+gap] = list[j];
        }
        list[j+gap] = temp;
    }
}

可以看到,希爾排序不過是一個不斷進行插入排序的過程。在這個過程中,去不斷地調整序列的頭位置 head 和間隔 gap 的值。而這裡用到的插入排序演算法,跟之前相比做了一點小調整,修改了待排元素的索引,加上了對應的 gap 偏移。

四、演算法分析

  • 開始的時候 gap 值較大,子序列中的元素較少,排序速度較快,而且元素一次移動的距離較大。
  • 隨著排序的進行, gap 值逐漸縮小,子序列中元素個數逐漸變多,但由於前面的排序結果,子序列基本有序,因此排序也很快。
  • 從圖示的例子中看出,兩個關鍵字為25的元素,在排序前後,它們的相對位置已經發生變化,所以希爾排序是一種不穩定的排序。
  • 希爾排序需要比較次數和移動次數約為 n ^ 1.3 ,當 n 趨於無窮時可減少到 n(log2(n))^2

五、總結

  • 希爾排序的時間複雜度為 O( n(log2(n))^2 )
  • 希爾排序是一種不穩定的排序。

獲取更佳的閱讀體驗,請訪問原文地址 【Lyman's Blog】希爾排序——重溫排序(二)

相關文章