C++排序演算法之希爾排序__web

來源:互聯網
上載者:User
希爾排序
(1)演算法介紹      希爾排序又叫做縮小增量排序,其本質還是插入排序,只不過是將待排序的序列按照某種規則分成幾個子序列,分別對這幾個子序列進行直接插入排序。這個規則就是增量。 例如,先以增量5來分割序列,即將下標為1,6,11,16........的記錄分成一組,將下標為2,7,12,17,........的記錄分成另外一組等,然後分別對這些組進行直接插入排序,這就是一趟希爾排序。將上面排列好序的整個序列,按照同樣的方式再以增量3分割,在進行一趟希爾排序,最後以增量1分割整個序列,其實就是對整個序列進行一趟直接插入排序。,從而完成整個希爾排序。      注意到增量5、3、1是逐漸縮小的,這就是縮小增量排序的由來。而我們知道,直接插入排序適合於序列基本有序的情況,希爾排序的每趟排序,都會使整個序列變得更加有序,等整個序列基本有序了,再來一趟直接插入排序,這樣會使排序效率更高,這就是希爾排序的意思。
關於直接插入排序可參考:點擊開啟連結
(2)執行流程      下面舉例說明希爾排序的執行過程 原始序列:3  5  2  9  7  8  4  1  6  10 1)以增量5分割序列,得到以下幾個子序列: 子序列1:3                         8 子序列2:     5                         4 子序列3:          2                         1 子序列4:               9                         6 子序列5:                    7                         10 分別對這5個子序列進行直接插入排序,得到: 子序列1:3                         8 子序列2:     4                         5 子序列3:          1                         2 子序列4:               6                         9 子序列5:                    7                         10 一趟希爾排序結束,結果為:3  4  1  6  7  8  5  2  9  10 2)再以增量3分割序列,得到以下幾個子序列: 子序列1:3              6                5               10 子序列2:     4               7               2 子序列3:          1                8               9   分別對這3個子序列進行直接插入排序,得到: 子序列1:3              5                6              10 子序列2:     2               4               7 子序列3:          1                8               9 一趟希爾排序結束,結果為:3  2  1  5  4  8  6  7  9  10 3)最後以增量1分割,即對上面的結果全體進行一次直接插入排序,從而完成整個希爾排序。 最後希爾排序的結果為:1  2  3  4  5  6  7  8  9  10
代碼實現如下:
#include <iostream>#include <vector>using namespace std;/*希爾排序演算法:平均時間複雜度為 O(1);空間複雜度為 O(1) 注意:希爾排序的增量序列的最後一個值一定是1,其次增量序列中的值每一除1之外的公因子*/void shellSort(vector<int>& R){int gap;                                                                //用來設定增量for (gap = 5; gap > 0; gap=gap-2)                                      //設定增量{for (int i = 0; i < gap; i++)                                   //對增量之間的值迴圈進行直接插入排序{for (int j = i + gap; j < R.size(); j = j + gap)        //對每一組元素進行直接插入排序{int temp = R[j];                                //相當於無序序列中的第一個數int k = j - gap;                                //想當於有序序列中的數while (k >= 0 && R[k] > temp){R[k + gap] = R[k];k = k - gap;}R[k + gap] = temp;}}}}void main(){vector<int> R = { 3,  5,  2,  9,  7,  8,  4,  1,  6,  10 };cout << "排序前:";for (auto x:R)cout << x << " ";cout << endl;shellSort(R);cout << "排序後:";for (auto x:R)cout << x << " ";cout << endl;}

運行結果:

複雜度分析: (1)時間複雜度 平均時間複雜度為O(nlogn) (2)空間複雜度 希爾排序的空間複雜度同直接插入排序一樣,為O(1)。
(3)希爾排序模板
/*shell排序模板*//*一種較好的增量選取方式為{1,5,19,41,109,...},該序列中的項或者是9*4i(4的i次方,後同)-9*2i+1的形式,或者是4i-3*2i+1的形式*/template <typename Comparable>void shellsort(vector<Comparable> & a){for (int gap = a.size() / 2; gap > 0; gap /= 2)           //增量選取方式(不理想)採用Shell建議的 h(t)=N/2、h(t-1) = h(t)/2、.......{for (int i = gap; i < a.size(); ++i){Comparable tem = std::move(a[i]);int j = i;for (; j >= gap&&tem < a[j - gap]; j -= gap)   // j 為什麼要>=gap。因為最前面一個元素為j-gap,所以j最小為gapa[j] = std::move(a[j - gap]);a[j] = std::move(tem);}}}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.