高级排序:希尔排序

导读:本篇文章讲解 高级排序:希尔排序,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

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

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

图1
如图,假设输入数组为{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 h = a.length / 2; //令初始h为数组长度的一半
        while (h >= 1) { //每一个不同的h 各视为一次完整的插入排序!
            for (int i = h; i < a.length; i++) { //第一轮为待排序第一个数字的范围,索引0视为已排序,所以从h开始
                for (int j = i; j >=h; j = j - h) { // j移动的步长为h,由普通插入排序的j--,变成j=j-h
                    if(a[j-h]>a[j]){
                        swap(a,j-1,j);
                    }else{
                        break;
                    }
                }
            }
        h=h/2;
        }
    }

    private static void swap(int[] a ,int i,int j){
        int x=a[i];
        a[i]=a[j];
        a[j]=x;
    }


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

测试结果:[1, 2, 4, 6, 7, 9]

需要注意的地方:

  1. 每一个不同的h 各视为一次完整的插入排序!
  2. 和基本的插入排序一样,外层循环i即待排序数,待排序数依次往后至最后一个数,所以i<a.length
  3. for内层循环时比较的是待排序数a[j-h]和a[j],所以j=i。每次跨越的步长为h,所以j=j-h。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/89398.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!