zoukankan      html  css  js  c++  java
  • 希尔排序

    希尔排序是插入排序的优化算法,时间复杂度为O(nlogn),也称为增量缩小的算法.

    希尔排序使用了一个序列h1,h2,h3...hk,称为增量序列,只要h1=1 任何增量序列都是可行的,不过有些增量序列可能会比另外一些增量序列更好一点.

    在使用增量hk排序以后,对每个i,都有a[i]<=a[i+k],即相隔k个的元素都已经排序,此时称文件是hk排序的.
    对希尔排序来说一个重要的性质就是,一个hk排序的文件,保持他的hk有序性,即使用下一个增量(hk-1)排序后,之前基于hk的排序依然是有效的.

    举例说明
    数组a = [4,2,1,9,3,5,8,6,7]
    通常我们选取的增量序列是 hk= length/2(向下取整) hk-1 = hk/2(向下取整) ... h1 =1(更好的增量序列,暂时不讨论)

    那么对a来说我们选取的增量序列就是 4,2,1

    原数组a = [4,2,1,9,3,5,8,6,7]
    第一轮,增量序列为4
    a[4]=3,a[0]=4,{4,3}3插入排序(改变)
    a=[3,2,1,9,4,5,8,6,7]

    a[5]=5,a[1]=2,{2,5}5插入排序(不变)
    a=[3,2,1,9,4,5,8,6,7]

    a[6]=8,a[2]=1,{1,8}8插入排序(不变)
    a=[3,2,1,9,4,5,8,6,7]

    a[7]=6,a[3]=9,{9,6}6插入排序(改变)
    a=[3,2,1,6,4,5,8,9,7]

    a[8]=7,a[4]=4,{4,7}7插入排序(不变)
    a=[3,2,1,6,4,5,8,9,7]

    第一轮结束.a=[3,2,1,6,4,5,8,9,7]

    第二轮排序,增量序列为2
    a[2]=1,a[0]=3,{3,1}1插入排序(改变)
    a=[1,2,3,6,4,5,8,9,7]

    a[3]=6,a[1]=2,{2,6}6插入排序(不变)
    a=[1,2,3,6,4,5,8,9,7]

    a[4]=4,a[2]=3,a[0]=1,{1,3,4}4插入排序(不变)
    a=[1,2,3,6,4,5,8,9,7]

    a[5]=5,a[3]=6,a[1]=2,{2,6,5}5插入排序(改变)
    a=[1,2,3,5,4,6,8,9,7]

    a[6]=8,a[4]=4,a[2]=3,a[0]=1,{1,3,4,8}8插入排序(不变)
    a=[1,2,3,5,4,6,8,9,7]

    a[7]=9,a[5]=6,a[3]=5,a[1]=2,{2,5,6,9}9插入排序(不变)
    a=[1,2,3,5,4,6,8,9,7]

    a[8]=7,a[6]=8,a[4]=4,a[2]=3,a[0]=1,{1,3,4,8,7}7插入排序(改变)
    a=[1,2,3,5,4,6,7,9,8]

    第二轮排序结束.a=[1,2,3,5,4,6,7,9,8]

    第三轮排序开始,增量为1

    a[1]=2,a[0]=1,{1,2}2插入排序(不变)
    a=[1,2,3,5,4,6,7,9,8]

    a[2]=3,a[1]=2,a[0]=1,{1,2,3}3插入排序(不变)
    a=[1,2,3,5,4,6,7,9,8]

    a[3]=5,a[2]=3,a[1]=2,a[0]=1,{1,2,3,5}5插入排序(不变)
    a=[1,2,3,5,4,6,7,9,8]

    a[4]=4,a[3]=5,a[2]=3,a[1]=2,a[0]=1,{1,2,3,5,4}4插入排序(改变)
    a=[1,2,3,4,5,6,7,9,8]

    a[5]=6,a[4]=5,a[3]=4,a[2]=3,a[1]=2,a[0]=1,{1,2,3,4,5,6}6插入排序(不变)
    a=[1,2,3,4,5,6,7,9,8]

    a[6]=7,a[5]=6,a[4]=5,a[3]=4,a[2]=3,a[1]=2,a[0]=1,{1,2,3,4,5,6,7}7插入排序(不变)
    a=[1,2,3,4,5,6,7,9,8]

    a[7]=9,a[6]=7,a[5]=6,a[4]=5,a[3]=4,a[2]=3,a[1]=2,a[0]=1,{1,2,3,4,5,6,7,9}9插入排序(不变)
    a=[1,2,3,4,5,6,7,9,8]

    a[8]=8,a[7]=9,a[6]=7,a[5]=6,a[4]=5,a[3]=4,a[2]=3,a[1]=2,a[0]=1,{1,2,3,4,5,6,7,9,8}8插入排序(改变)
    a=[1,2,3,4,5,6,7,8,9]

    第三轮排序完毕,整体排序完毕
    数组a=[1,2,3,4,5,6,7,8,9]

         

     1     public static <T extends Comparable<? super T>> void shell(T[] arr) {
     2         int length = arr.length;
     3         for (int step = length / 2; step > 0; step /= 2) {
     4             for (int i = step; i < length; i++) {
     5                 int j = 0;
     6                 T tmp = arr[i];
     7                 for (j = i; j >= step && tmp.compareTo(arr[j - step]) < 0; j -= step) {
     8                     arr[j] = arr[j - step];
     9                 }
    10                 arr[j] = tmp;
    11             }
    12 
    13         }
    14     }
    View Code
  • 相关阅读:
    [PHP] yield沟通函数循环内外
    [Linux] scp本地服务器和远程服务器拷贝文件
    [Linux] 大数据库导出大文件统计并去重
    [Go] golang连接查询mysql
    [日常] 解决mysql不允许外部访问
    [Go] golang创建目录写文件判断文件
    [日常] imap协议读取邮件
    [Go] golang使用github里的imap类库
    [Go] golang无缓冲通道实现工作池控制并发
    [Go] golang的range循环遍历通道
  • 原文地址:https://www.cnblogs.com/coldridgeValley/p/4926625.html
Copyright © 2011-2022 走看看