数据结构第九周笔记(2)——排序(上)(慕课浙大版本--XiaoYu)

104 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情

9.2 希尔排序(by Donald Shell)

基本思路:利用了插入排序的简单,同时克服插入排序每次只交换相邻两个元素的缺点

image-20220817231030461

image-20220817231059520

image-20220817231127625

image-20220817231150119

到最后使用1-间隔的排序来保证序列有序(彻底的插入排序)。但此时这个序列已经基本有序了,大多数的逆序对已经在前面两趟5-间隔和3-间隔里面被消除掉了

image-20220817231759370

重要性质:3-间隔有序的序列还保持了前面5-间隔有序的这个性质(没有把上一步的结果变坏)

image-20220817231818451

希尔增量序列

  1. 原始希尔排序image-20220817231915152

  2. 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;
            }
        }
    }
    

    最坏情况:image-20220817235114397

    O是一个上界(可能达不到)

    image-20220817235222549

    增长速度跟N²一样快

    坏例子

    image-20220817235503572

    增量元素不互质,则小增量可能根本不起作用

    更多的增量序列

    image-20220817235733415

    用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;
             }
    }