数据结构之希尔排序
图例
首先,以5为间隔对各个子序列进行插入排序,然后再以3为间隔进行插入排序,最后以1为间隔进行插入排序。
主要思想
- 主要思想:定义增量序列
D
M
>
D
M
−
1
>
⋯
>
D
1
=
1
D_M>D_{M-1}>\cdots>D_1=1
DM>DM−1>⋯>D1=1
注:最后一步必须是以1为间隔 - 对每个
D
k
D_k
Dk进行
“
D
k
−
间
隔
"
“D_k-间隔"
“Dk−间隔"排序
(
k
=
M
,
M
−
1
,
…
,
1
)
(k=M,M-1,\ldots,1)
(k=M,M−1,…,1)
注: “ D k − 间 隔 " 有 序 的 序 列 , 再 执 行 “ D k − 1 − 间 隔 " 排 序 后 , 仍 然 是 “ D k − 间 隔 ” 有 序 的 “D_k-间隔"有序的序列,再执行“D_{k-1}-间隔"排序后,仍然是“D_k-间隔”有序的 “Dk−间隔"有序的序列,再执行“Dk−1−间隔"排序后,仍然是“Dk−间隔”有序的
(人话就是:打个比方,本来以5为间隔递增排序,然后以3为间隔递增排序后,这个序列还是可以以5为间隔递增的)
原始希尔排序算法
D M ( 最 初 间 隔 ) = ⌊ N / 2 ⌋ , D K ( 间 隔 增 量 ) = ⌊ D k + 2 / 2 ⌋ D_M(最初间隔)=\left \lfloor N/2 \right \rfloor,D_K(间隔增量)=\left\lfloor D_{k+2}/2 \right\rfloor DM(最初间隔)=⌊N/2⌋,DK(间隔增量)=⌊Dk+2/2⌋
void shell_sort(int a[], int N) {
int D,P,tmp,i;
for (D = N / 2; D > 0; D /= 2) {/*希尔增量序列*/
for (P = D; P < N; P++)/*插入排序*/
{
tmp = a[P];
for ( i = P; i>=D && a[i - D] > tmp; i-=D) {
a[i] = a[i - D];
}
a[i] = tmp;
}
}
}
注:希尔排序里的插入排序把原版的1全部换成了 D ( 间 隔 增 量 ) D(间隔增量) D(间隔增量)。
原始希尔排序时间复杂度
最 坏 情 况 : θ ( N 2 ) ( θ : 既 是 上 界 也 是 下 界 ) 最坏情况:\theta(N^2)(\theta:既是上界也是下界) 最坏情况:θ(N2)(θ:既是上界也是下界)
- 最坏情况
此时前三次都没有进行元素交换,相当于白白浪费了。
增量元素不 互质,则小增量可能根本不起作用。
更多增量序列
-
Hibbard序列
D k = 2 k − 1 , D_k=2^k-1, Dk=2k−1,这样保证了相邻元素互质。
最坏情况: T = θ ( N 3 2 ) T=\theta(N^{3\over2}) T=θ(N23)
猜想: T a v g = θ ( N 5 4 ) T_{avg}=\theta(N^{5\over4}) Tavg=θ(N45) -
Sedgewick增量序列
{ 1 , 5 , 19 , 41 , 109 , … } \left \{ 1,5,19,41,109,\ldots\right \} {1,5,19,41,109,…}
猜想: T a v g = O ( N 7 6 ) , T w o r s t = O ( N 4 3 ) T_{avg}=O(N^{7\over6}),T_{worst}=O(N^{4\over3}) Tavg=O(N67),Tworst=O(N34)
以下是伪码描述:
void ShellSort( ElementType A[], int N )
{ /* 希尔排序 - 用Sedgewick增量序列 */
int Si, D, P, i;
ElementType Tmp;
/* 这里只列出一小部分增量 */
int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0};
for ( Si=0; Sedgewick[Si]>=N; Si++ )
; /* 初始的增量Sedgewick[Si]不能超过待排序列长度 */
for ( D=Sedgewick[Si]; D>0; D=Sedgewick[++Si] )
for ( P=D; P<N; P++ ) { /* 插入排序*/
Tmp = A[P];
for ( i=P; i>=D && A[i-D]>Tmp; i-=D )
A[i] = A[i-D];
A[i] = Tmp;
}
}
对于海量元素的情况,使用Sedgewick增量序列效果较好。
是否稳定
不稳定
GIF演示
以下是一个动图示例,便于理解: