資料結構與演算法——謝爾排序

readyao發表於2016-01-08

謝爾排序就是每隔一段距離的一個子序列進行插入排序;間隔是從大到小發生改變。謝爾排序也稱為縮減增量排序。

比如資料序列v: 81 94 11 96 12 35 17 95 28 58 41 75 15 (序列個數為13)

增量序列是:h1, h2, h3, ......, hk

謝爾增量序列是:hk=N/2, hk-1=hk/2, .....(N是序列的資料個數)

Hibbard增量序列:{1, 3, ..., 2^k-1}

Sedgewick增量序列:{1, 5, 19, 41, 109..}該序列中的項或者是9*4^i - 9*2^i + 1或者是4^i - 3*2^i + 1;

 間隔6的子序列是:

1

排序之前v: 81 94 11 96 12 35 17 95 28 58 41 75 15 

81, 17, 15 -----》子序列插入排序之後是-----15, 17, 81

排序之後v: 15 94 11 58 12 35 17 95 28 96 41 75 81

2

排序之前v: 15 94 11 58 12 35 17 95 28 96 41 75 81

94, 95     -----》子序列插入排序之後是-----94, 95

排序之後v: 15 94 11 58 12 35 17 95 28 96 41 75 81

3

排序之前v: 15 94 11 58 12 35 17 95 28 96 41 75 81

11, 28     -----》子序列插入排序之後是-----11, 28

排序之後v: 15 94 11 58 12 35 17 95 28 96 41 75 81

4

排序之前v: 15 94 11 58 12 35 17 95 28 96 41 75 81

58, 96     -----》子序列插入排序之後是-----》 58, 96

排序之後v: 15 94 11 58 12 35 17 95 28 96 41 75 81

5

排序之前v: 15 94 11 58 12 35 17 95 28 96 41 75 81

12, 41     -----》子序列插入排序之後是-----》 12, 41

排序之後v: 15 94 11 58 12 35 17 95 28 96 41 75 81

6

排序之前v: 15 94 11 58 12 35 17 95 28 96 41 75 81

35, 75     -----》子序列插入排序之後是-----》 35, 75

排序之後v: 15 94 11 58 12 35 17 95 28 96 41 75 81

 

所有的間隔為6的子序列排序之後的序列輸出是:v: 15 94 11 58 12 35 17 95 28 96 41 75 81

(見輸出結果6: 15 94 11 58 12 35 17 95 28 96 41 75 81):

 間隔3的子序列是:

1

排序之前v: 15 94 11 58 12 35 17 95 28 96 41 75 81 

15, 58, 17, 96, 81 -----》子序列插入排序之後是-----15, 17, 58, 81, 96

排序之後v: 15 94 11 17 12 35 58 95 28 81 41 75 96

2

排序之前v: 15 94 11 17 12 35 58 95 28 81 41 75 96

94, 12, 95, 41     -----》子序列插入排序之後是-----12, 41, 94, 95

排序之後v: 15 12 11 17 41 35 58 94 28 81 95 75 96

3

排序之前v: 15 12 11 17 41 35 58 94 28 81 95 75 96

11, 35, 28, 75     -----》子序列插入排序之後是-----11, 28, 35, 75

排序之後v: 15 12 11 17 41 28 58 94 35 81 95 75 96

(其實到這一步的時候,這個已經是間隔為3這種情況下最後的輸出結果了。

見輸出結果3: 15 12 11 17 41 28 58 94 35 81 95 75 96

 間隔1的子序列是:

v:15 12 11 17 41 28 58 94 35 81 95 75 96

此時其實就相當於是直接對v進行一次插入排序。

排序輸出結果是:

v: 11 12 15 17 28 35 41 58 75 81 94 95 96

執行輸出結果:

v: 81 94 11 96 12 35 17 95 28 58 41 75 15 

6: 15 94 11 58 12 35 17 95 28 96 41 75 81 

3: 15 12 11 17 41 28 58 94 35 81 95 75 96 

1: 11 12 15 17 28 35 41 58 75 81 94 95 96 

v: 11 12 15 17 28 35 41 58 75 81 94 95 96


 


用謝爾增量實現謝爾排序的原始碼:

/*************************************************************************
	> File Name: shellsort.cpp
	> Author: 
	> Mail: 
	> Created Time: 2016年01月08日 星期五 22時16分24秒
 ************************************************************************/

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;



int main()
{
    vector<int> v;
    v.push_back(81);
    v.push_back(94);
    v.push_back(11);
    v.push_back(96);
    v.push_back(12);
    v.push_back(35);
    v.push_back(17);
    v.push_back(95);
    v.push_back(28);
    v.push_back(58);
    v.push_back(41);
    v.push_back(75);
    v.push_back(15);

    cout << "v: ";
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
    cout << endl;

    for (int gap = v.size()/2; gap > 0; gap /= 2){//增量序列
        for (int i = gap; i < v.size(); ++i){//對間隔為gap的子序列進行插入排序
            int tmp = v[i];
            int j = i;

            for ( ; j >= gap && tmp < v[j-gap]; j -= gap)
                v[j] = v[j-gap];

            v[j] = tmp;
            
        }
        cout << gap << ": ";
        copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
        cout << endl;
    }

    cout << "v: ";
    copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
    cout << endl;

    return 0;
}




相關文章