开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情
9.2 希尔排序(by Donald Shell)
基本思路:利用了插入排序的简单,同时克服插入排序每次只交换相邻两个元素的缺点
到最后使用1-间隔的排序来保证序列有序(彻底的插入排序)。但此时这个序列已经基本有序了,大多数的逆序对已经在前面两趟5-间隔和3-间隔里面被消除掉了
重要性质:3-间隔有序的序列还保持了前面5-间隔有序的这个性质(没有把上一步的结果变坏)
希尔增量序列
-
原始希尔排序
-
void Shell_Sort( ElementType A[],int N ) { for(D = M/2; D > 0; D /= 2 ){//希尔增量序列 for( P = D; P < N; P++ ){//插入排序,D是距离(第0张牌在我手里,下一张牌从第D张牌开始摸) Tmp = A[P]; for( i = P; i >= D && A[i - D] > Tmp;i -= D ) A[i] = A[i - D]; A[i] = Tmp; } } }最坏情况:
O是一个上界(可能达不到)
增长速度跟N²一样快
坏例子:
增量元素不互质,则小增量可能根本不起作用
更多的增量序列
用Sedgewick增量序列 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; } }