zoukankan      html  css  js  c++  java
  • 希尔排序算法原理与实现

    1.问题描述

    输入:n个数的序列<a1,a2,a3,...,an>。
    输出:原序列的一个重排<a1*,a2*,a3*,...,an*>;,使得a1*<=a2*<=a3*<=...<=an*。

    2. 问题分析

    例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:

    13 14 94 33 82
    25 59 94 65 23
    45 27 73 25 39
    10
    

    然后我们对每列进行排序:

    10 14 73 25 23
    13 27 94 33 39
    25 59 94 65 82
    45
    

    将上述四行数字,依序接在一起时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:

    10 14 73
    25 23 13
    27 94 33
    39 25 59
    94 65 82
    45
    

    排序之后变为:

    10 14 13
    25 23 33
    27 25 59
    39 65 73
    45 94 82
    94
    

    最后以1步长进行排序(此时就是简单的插入排序了)。

    对于每一列的排序,可以采用任意一个算法,本文采用变形的InsertSort( CVector<T> &vec,int start, int end, int step = 1 )。


    3. 算法实现

    template <typename T>
    void InsertSort( CVector<T> &vec,int start, int end, int step = 1 )
    {
        for ( size_t i=start+step; i<vec.GetSize(); i+=step )
        {
            T temp = vec[i];
            int j = i-step;
    
            while ( j >= start && vec[j] > temp )
            {
                vec[j+step] = vec[j];
                j-=step;
            }
    
            vec[j+step] = temp;
        }
    }
    
    template <typename T>
    void ShellSort( CVector<T> &vec )
    {
        const int gaps[10] = {1, 5, 19, 41, 109, 209, 505, 929, 2161, 3905};
        int i_gap = 9;
        int size = vec.GetSize();
    
        while( gaps[i_gap] >=size-1  )
            i_gap--;
    
        for( int gap = gaps[i_gap]; i_gap>=0; gap=gaps[--i_gap] )
        {
            //traversal each element in block
            for ( int i=0; i<gap; i++ )
            {
                //ShellSortPart( vec, i, gap  );
                InsertSort<int>( vec, i, size-1, gap );
            }
        }
    }

    测试:

    #define  DATA_MAGNITUDE 100
    
    double random(double start, double end)
    {
        return start+(end-start)*rand()/(RAND_MAX + 1.0);
    }
    
    int main(int argc, char **argv)
    {
        CVector<int> vec1(10,2);
        CVector<int> vec2(DATA_MAGNITUDE);
        CVector<char> vec_txt(1000,'a');
    
        //====================================================================
        srand( unsigned(time(0)));
        for ( int i=0; i<DATA_MAGNITUDE; i++ )
        {
            //vec2.PushBack( (int)rand()%DATA_MAGNITUDE );
            vec2.PushBack( (int)random(0, DATA_MAGNITUDE) );
        }
        unsigned int size = 20<DATA_MAGNITUDE? 20:DATA_MAGNITUDE;
        for ( size_t i =0; i < size; i++ )
        {
            cout<<vec2[i]<<" ";
        }
        cout<<endl;
    
        //InsertSort<int>( vec2, 0, vec2.GetSize()-1 );
        //BubbleSort<int>( vec2 );
        //SelectSort<int>( vec2 );
        ShellSort<int>( vec2 );
    
        for ( size_t i =0; i < size; i++ )
        {
            cout<<vec2[i]<<" ";
        }
        cout<<endl;
        return 0;
    }

    4. 算法分析

    希尔排序的性能与选取的步长直接相关。

    General term (k ≥ 1) Concrete gaps Worst-case
    time complexity
    Author and year of publication
    lfloor N / 2^k 
floor leftlfloorfrac{N}{2}
ight
floor,        leftlfloorfrac{N}{4}
ight
floor, ldots, 1 Theta(N^2) [when N=2p] Shell, 1959[1]
    2 lfloor N / 2^{k+1} 
floor + 1 2 leftlfloorfrac{N}{4}
ight
floor + 1, ldots, 3, 1 Theta(N^{3/2}) Frank & Lazarus, 1960[5]
    2^k - 1 1, 3, 7, 15, 31, 63, ldots Theta(N^{3/2}) Hibbard, 1963[6]
    2^k + 1, prefixed with 1 1, 3, 5, 9, 17, 33, 65, ldots Theta(N^{3/2}) Papernov & Stasevich, 1965[7]
    successive numbers of the form 2^p 3^q 1, 2, 3, 4, 6, 8, 9, 12, ldots Theta(N log^2 N) Pratt, 1971[8]
    (3^k - 1) / 2, not greater than lceil N / 3 
ceil 1, 4, 13, 40, 121, ldots Theta(N^{3/2}) Knuth, 1973[9]
    prod  limits_{scriptscriptstyle 0le q<ratop           scriptscriptstyle q
eq(r^2+r)/2-k}a_q, hbox{where}
    r = leftlfloor sqrt{2k+sqrt{2k}} 
ight
floor,
    a_q=min{ninmathbb{N}colon nge(5/2)^{q+1},
    forall pcolon0le p<qRightarrowgcd(a_p,n)=1}
    1, 3, 7, 21, 48, 112, ldots O(N e^sqrt{8ln(5/2)ln N}) Incerpi & Sedgewick, 1985[10]
    4^k + 3cdot2^{k-1} + 1, prefixed with 1 1, 8, 23, 77, 281, ldots O(N^{4/3}) Sedgewick, 1986[3]
    9(4^{k-1}-2^{k-1})+1, 4^{k+1}-6cdot2^k+1 1, 5, 19, 41, 109, ldots O(N^{4/3}) Sedgewick, 1986[3]
    h_k = maxleft{leftlfloor 5h_{k-1}/11 
ight
floor, 1
ight}, h_0 = N leftlfloor frac{5N}{11} 
ight
floor, leftlfloor frac{5}{11}leftlfloor frac{5N}{11} 
ight
floor
ight
floor, ldots, 1  ? Gonnet & Baeza-Yates, 1991[11]
    leftlceil frac{9^k-4^k}{5cdot4^{k-1}} 
ight
ceil 1, 4, 9, 20, 46, 103, ldots  ? Tokuda, 1992[12]
    unknown 1, 4, 10, 23, 57, 132, 301, 701  ? Ciura, 2001[13]
  • 相关阅读:
    【Balanced Binary Tree】cpp
    【Kernel Logistic Regression】林轩田机器学习技术
    【作业一】林轩田机器学习技术
    【Soft-Margin Support Vector Machine】林轩田机器学习技术
    【Kernal Support Vector Machine】林轩田机器学习技术
    【Dual Support Vector Machine】林轩田机器学习技法
    【Linear Support Vector Machine】林轩田机器学习技法
    【作业4】林轩田机器学习基石
    【Validation】林轩田机器学习基石
    mongodb之监控
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3188342.html
Copyright © 2011-2022 走看看