算法 希尔排序小述

版权声明:转载请声明: https://blog.csdn.net/MingJieZuo/article/details/83540526

一、概述

本节主要简单介绍一下希尔排序算法,希尔排序(Shell’s Sort)是插入排序的一种,又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止,摘自百度百科。从定义描述来看,很不好理解,反正我第一次看的时候是一脸懵逼,下面我就用自己的理解简单分析下。

二、分析

其实我觉得,希尔排序就是根据特定的规则进行多次的直接插入排序操作,就以数组[ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ]这个数组为例:

上面说的规则就是增量的计算,直接插入排序的增量为1,而我们希尔排序的增量是我们自己定义的,一般情况是中分取整,本例中则为10/2=5、5/2=2、2/2=1;所以我们需要进行3次直接插入排序,每次直接插入排序的增量分别为5、2、1

上面说的多次的求法,我们已经知道是3次,通常规则和次数都是相互对应的,但增量的计算方法我们是可以根据不同情况而变的。

增量为5的时候,我们第一轮的直接插入排序是怎样的呢?首先我们会将数组[ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ]根据增量分组,具体每组情况如下:
第1组:[9, 4],只有2个元素;
第2组:[8, 3],只有2个元素;
第3组:[7, 2],只有2个元素;
第4组:[6, 1],只有2个元素;
第5组:[5, 0],只有2个元素;
之后我们每组分别进行直接插入排序操作,思路就是有序和无序两部分,无序不断插入到有序之中,不清楚的可以查看我的直接插入排序的介绍:
第1组:直接插入排序后[4, 9];
第2组:直接插入排序后[3, 8];
第3组:直接插入排序后[2, 7];
第4组:直接插入排序后[1, 6];
第5组:直接插入排序后[0, 5];
所以当第1轮增量为5的循环结束后,原始数据变为[4, 3, 2, 1, 0, 9, 8, 7, 6, 5]

在这里插入图片描述

增量为2的时候,方法思路同上,首先我们将之分组,每组情况如下:
第1组:[4, 2, 0, 8, 6],有5个元素;
第2组:[3, 1, 9, 7, 5],有5个元素;
之后我们每组分别进行直接插入排序操作:
第1组:直接插入排序后[0, 2, 4, 6, 8];
第2组:直接插入排序后[1, 3, 5, 7, 9];
所以当第2轮增量为2的循环结束后,原始数据变为[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

在这里插入图片描述

增量为1的时候,已经跟我们直接插入排序的算法完成一样了,现在只有一组数据了:
第1组:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],全部元素;
之后我们每组分别进行直接插入排序操作:
第1组:直接插入排序后[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],因为这个序列比较特殊,当增量为1的时候不需要移位插入;

在这里插入图片描述

如果对于希尔排序还不是很清晰,可以结合代码看下哦,这样我觉得效果更佳

三、代码展示

希尔排序算法的代码如下,主要分为3个循环体,外层循环控制要进行直接插入排序的次数,内两层为直接插入排序算法:

    private static int[] shellSort(int[] array) {
        int length = array.length;
        // 分为几轮直接插入排序
        for(int gap = length/2; gap>=1; gap/=2) {
            int i = gap;
            for(; i<length; i+=gap){
                int temp = array[i];
                int j = i-gap;
                for(; j>=0&&temp<array[j]; j-=gap){
                    array[j+gap] = array[j];
                }
                array[j+gap] = temp;
            }
        }
        return array;
    }

值得注意的是,由于希尔排序会进行多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以希尔排序是不稳定的。

四、总结

当然代码编写并不是固定的,肯定会有很多变形格式,其实我们研究的也是希尔排序的思想和每种写法的效率问题。如果想要查看更多算法基础,去我的博客目录里查看吧,因为关于每块知识点的介绍,博客单节写的比较零散,不容易查找。

猜你喜欢

转载自blog.csdn.net/MingJieZuo/article/details/83540526