栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

高级排序:希尔排序

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

高级排序:希尔排序

一.概述
希尔排序是插入排序的一种,又称“缩小增量排序”,是插入排序算法的一种更高效的改进版本。
在学习插入排序的时候,倒序将待排序的第一个数和前面已排序的数进行比较再往前插时,必须依次往前,效率较低。故可通过增加步长h来提高效率。

二.原理
1.选定一个增长量(步长)h,按照增长量h对数据进行分组;
2.对分好组的每一组数据为一轮,每一轮内进行插入排序;
3.按照规则减少增长量h,最后减为1,重复第二步操作

注:关于增长量h的确定好像不唯一,我看的黑马视频里是这样规定的:
初始值:int h=1
while(h h=2h+1; }
减小规则: h=h/2
要更简便一点,h初始值应该也可以直接令h=a.length/2


如图,假设输入数组为{9,1,2,5,7,4,8,6,3,5} , 按照插入排序的思想,将数组分为已排序和未排序两部分。在插入排序中,当数组为初始状态时,将索引0处的数视为已排序,索引1到n-1为未排序部分。而在希尔排序中,索引为0的数依旧视为已排序,而由于未排序数字倒序向已排序数字进行比较时存在一个增长量(步长)h,所以初始状态时,索引h的数字为待排序数字。
第一轮:为了方便演示,令h的第一个值为5,即索引=5为最初的待排序数字也就是“4”。将4和与其距离h的已排序数比较,此时已排序数字为索引0处的“9” ,4<9,所以不进行插入。由于待排序数字每次倒序遍历时,要和已排序数字的距离为h的倍数,所以此时“4”只能和“9”比较。
第一个待排序数“4”比较结束,使用第二个待排序数字“8”向前遍历,数字“8”的索引为6,与其比较的数的索引为6-5=1,即数字“1”。1<8,不将8进行插入…同理进行后序排列。
第二轮,h为2,第一个待排序数字为索引=h=2的数,即“2”,2与索引为0的数“4”比较,2<4,所以2和4交换。…后面的同理

三.java代码实现

public class shell {
    public static void sort(int[] a){
        int n=a.length;
        int h=1;
        while(h=1){
            for(int i=h;i=h;j-=h){
                    if(a[j-h]>a[j]){
                        swap(a,j-h,j);
                    }else{
                        break;
                    }
                }
            }
            h=h/2;
        }
    }
    public static  void swap(int[] a,int i,int j){
        int k=a[i];
        a[i]=a[j];
        a[j]=k;
    }

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

运行结果:[1, 2, 3, 4, 5, 5, 6, 7, 8, 9]

需要注意的地方:

  1. 和基本的插入排序一样,外层循环i即待排序数,待排序数依次往后至最后一个数,所以i
  2. for内层循环时比较的是待排序数a[j]和a[j-h],所以j=i,而h>=j。而待排序数向前比较时,每次跨越的步长为h,所以j=j-h。
  3. h减少规则在while循环内,for循环外。

这段代码可能没有那么简洁,但对于我这种初学者来说能理解就行。
第一次动手写博客,感觉的确能让自己更专注的去思考,有助于学习。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/684815.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号