图解排序算法之希尔排序Java实现


Posted in Java/Android onJune 26, 2021

一、基本思想

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

简单插入排序很循规蹈矩,不管数组分布是怎么样的,依然一步一步的对元素进行比较,移动,插入,比如[5,4,3,2,1,0]这种倒序序列,数组末端的0要回到首位置很是费劲,比较和移动元素均需n-1次。而希尔排序在数组中采用跳跃式分组的策略,通过某个增量将数组元素划分为若干组,然后分组进行插入排序,随后逐步缩小增量,继续按组进行插入排序操作,直至增量为1。希尔排序通过这种策略使得整个数组在初始阶段达到从宏观上看基本有序,小的基本在前,大的基本在后。然后缩小增量,到增量为1时,其实多数情况下只需微调即可,不会涉及过多的数据移动。

我们来看下希尔排序的基本步骤,在此我们选择增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择我们可以用一个序列来表示,{n/2,(n/2)/2...1},称为增量序列。希尔排序的增量序列的选择与证明是个数学难题,我们选择的这个增量序列是比较常用的,也是希尔建议的增量,称为希尔增量,但其实这个增量序列不是最优的。此处我们做示例使用希尔增量。

图解排序算法之希尔排序Java实现

二、代码实现

在希尔排序的理解时,我们倾向于对于每一个分组,逐组进行处理,但在代码实现中,我们可以不用这么按部就班地处理完一组再调转回来处理下一组(这样还得加个for循环去处理分组)比如[5,4,3,2,1,0] ,首次增量设gap=length/2=3,则为3组[5,2] [4,1] [3,0],实现时不用循环按组处理,我们可以从第gap个元素开始,逐个跨组处理。同时,在插入数据时,可以采用元素交换法寻找最终位置,也可以采用数组元素移动法寻觅。希尔排序的代码比较简单,如下:

package sortdemo;

import java.util.Arrays;

public class ShellSort {
    public static void main(String []args){
        int []arr ={1,4,2,7,9,8,3,6};
        sort(arr);
        System.out.println(Arrays.toString(arr));
        int []arr1 ={1,4,2,7,9,8,3,6};
        sort1(arr1);
        System.out.println(Arrays.toString(arr1));
    }

    /**
     * 希尔排序 针对有序序列在插入时采用交换法
     * @param arr
     */
    public static void sort(int []arr){
        //增量gap,并逐步缩小增量
       for(int gap=arr.length/2;gap>0;gap/=2){
           //从第gap个元素,逐个对其所在组进行直接插入排序操作
           for(int i=gap;i<arr.length;i++){
               int j = i;
               while(j-gap>=0 && arr[j]<arr[j-gap]){
                   //插入排序采用交换法
                   swap(arr,j,j-gap);
                   j-=gap;
               }
           }
       }
    }

    /**
     * 希尔排序 针对有序序列在插入时采用移动法。
     * @param arr
     */
    public static void sort1(int []arr){
        //增量gap,并逐步缩小增量
        for(int gap=arr.length/2;gap>0;gap/=2){
            //从第gap个元素,逐个对其所在组进行直接插入排序操作
            for(int i=gap;i<arr.length;i++){
                int j = i;
                int temp = arr[j];
                if(arr[j]<arr[j-gap]){
                    while(j-gap>=0 && temp<arr[j-gap]){
                        //移动法
                        arr[j] = arr[j-gap];
                        j-=gap;
                    }
                    arr[j] = temp;
                }
            }
        }
    }
    /**
     * 交换数组元素
     * @param arr
     * @param a
     * @param b
     */
    public static void swap(int []arr,int a,int b){
        arr[a] = arr[a]+arr[b];
        arr[b] = arr[a]-arr[b];
        arr[a] = arr[a]-arr[b];
    }
}

三、总结

本文介绍了希尔排序的基本思想及其代码实现,希尔排序中对于增量序列的选择十分重要,直接影响到希尔排序的性能。我们上面选择的增量序列{n/2,(n/2)/2...1}(希尔增量),其最坏时间复杂度依然为O(n2),一些经过优化的增量序列如Hibbard经过复杂证明可使得最坏时间复杂度为O(n3/2)。希尔排序的介绍到此为止。

以上就是图解排序算法之希尔排序Java实现的详细内容,更多关于希尔排序 Java的资料请关注三水点靠木其它相关文章!

Java/Android 相关文章推荐
springboot @ConfigurationProperties和@PropertySource的区别
Jun 11 Java/Android
在Java中Collection的一些常用方法总结
Jun 13 Java/Android
分析Java中Map的遍历性能问题
Jun 26 Java/Android
Java 泛型详解(超详细的java泛型方法解析)
Jul 02 Java/Android
使用@Value值注入及配置文件组件扫描
Jul 09 Java/Android
Java实现房屋出租系统详解
Oct 05 Java/Android
spring cloud eureka 服务启动失败的原因分析及解决方法
Mar 17 Java/Android
Netty分布式客户端处理接入事件handle源码解析
Mar 25 Java/Android
Java 超详细讲解ThreadLocal类的使用
Apr 07 Java/Android
Springboot-cli 开发脚手架,权限认证,附demo演示
Apr 28 Java/Android
Android开发EditText禁止输入监听及InputFilter字符过滤
Jun 10 Java/Android
Springboot中如何自动转JSON输出
Jun 16 Java/Android
Netty结合Protobuf进行编解码的方法
Java常用工具类汇总 附示例代码
Java多条件判断场景中规则执行器的设计
Java基于字符界面的简易收银台
springboot集成flyway自动创表的详细配置
idea搭建可运行Servlet的Web项目
Java Dubbo框架知识点梳理
You might like
php封装的验证码工具类完整实例
2016/10/19 PHP
PHP单例模式详解及实例代码
2016/12/21 PHP
PHP快速导出百万级数据到CSV或者EXCEL文件
2020/11/27 PHP
Javascript 代码也可以变得优美的实现方法
2009/06/22 Javascript
使用隐藏的new来创建对象
2011/03/29 Javascript
基于jquery可配置循环左右滚动例子
2011/09/09 Javascript
jquery禁止输入数字以外的字符的示例(纯数字验证码)
2014/04/10 Javascript
基于jQuery倾斜打开侧边栏菜单特效代码
2015/09/15 Javascript
JS函数的定义与调用方法推荐
2016/05/12 Javascript
jquery siblings获取同辈元素用法实例分析
2016/07/25 Javascript
微信小程序 教程之小程序配置
2016/10/17 Javascript
JavaScript实现设置默认日期范围为最近40天的方法分析
2017/07/12 Javascript
vue-cli项目根据线上环境分别打出测试包和生产包
2018/05/23 Javascript
JavaScript简单实现的仿微博留言功能示例
2019/01/17 Javascript
[58:18]2018DOTA2亚洲邀请赛3月29日 小组赛B组 iG VS Mineski
2018/03/30 DOTA
[06:07]DOTA2-DPC中国联赛 正赛 Ehome vs VG 选手采访
2021/03/11 DOTA
[59:53]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第二场 3月6日
2021/03/11 DOTA
[原创]使用豆瓣提供的国内pypi源
2017/07/02 Python
python实现AES加密解密
2019/03/28 Python
python字符串查找函数的用法详解
2019/07/08 Python
Python使用Pandas对csv文件进行数据处理的方法
2019/08/01 Python
Django和Flask框架优缺点对比
2019/10/24 Python
MoviePy常用剪辑类及Python视频剪辑自动化
2020/12/18 Python
法国家具及室内配件店:home24
2017/01/21 全球购物
马德里竞技官方网上商店:Atletico Madrid Shop
2019/03/31 全球购物
大学生个人简历自我评价
2013/11/16 职场文书
客户表扬信范文
2014/01/10 职场文书
大课间体育活动方案
2014/03/12 职场文书
中国梦口号
2014/06/13 职场文书
尊老爱亲美德少年事迹材料
2014/08/14 职场文书
环境卫生倡议书
2014/08/29 职场文书
行政文员岗位职责
2015/02/04 职场文书
2015年度电厂个人工作总结
2015/05/13 职场文书
nginx里的rewrite跳转的实现
2021/03/31 Servers
利用Python+OpenCV三步去除水印
2021/05/28 Python
Spring boot应用启动后首次访问很慢的解决方案
2021/06/23 Java/Android