希尔排序的个人理解及代码实现

希尔排序是一种插入排序的优化算法,通过设置间隔gap进行分组排序,逐步缩小gap以减少元素移动次数,提高排序效率。文章详细解释了希尔排序的思路,包括大间隔分组和逐步细化排序过程,并提供了Java实现代码示例。
摘要由CSDN通过智能技术生成

希尔排序


前言

希尔排序是插入排序的优化,学习希尔排序前,需要先深入理解插入排序。


以下是个人对此问题的理解;

一、简单了解希尔排序

希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。

希尔排序又称缩小增量排序,因 DL.Shell 于 1959 年提出而得名。

它通过比较相距一定间隔的元素来进行,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。

二、希尔排序思路

1.思路说明:

1.希尔排序是插入排序的优化:为解决插入排序中,数据距离其正确位置较远的问题;
即优化某一个值在插入排序中需要移动较远,需多次移动的情况;

如下图中的2,按直接插入排序,需移动到现在6的位置,需经过5次移动; 如果是有80000组数据呢?是不是可能要移动几万次。 而采用希尔可以是不是只需少量的移动,元素就到了大致范围了~

2.设定一定的gap值(初始值一般为 数组.length/2),采用gap跳跃性的分组,分组后对每一组进行插入排序(保证较小的数值可以尽快排到前面,较大得值尽快到后面),完成情况1优化;

图示:

3.逐渐缩小gap值(一般每次/2),重复完成2步骤,及不断优化情况1;
图示:
在这里插入图片描述

4.当gap达到1,及进行一次普通插入排序,完成即可保证100%元素顺序正确;
图示:
在这里插入图片描述

2.与普通排序对比的个人理解:

和普通插入排序相比,增加了前几轮以一定gap排序;
但每轮排序的移动元素是有意义的,通过gap大范围移动,迅速将元素放置到大致区域,大规模减少了后续的频繁移动,并大大减少了后续的排序时比较次数。
(效率远胜于普通插入排序)。

3.实现代码:

代码如下:

public class ShellSortTest {
    public static void main(String[] args) {
        int [] arr={25,5,30,1,7,0,99,100,88,7};
        shellSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    /**
     * 思路:
     * 1.希尔排序是插入排序的优化:为解决插入排序中(由小到大排序问题中),较小值位于最后面的请况;
     * 即优化某一个值在插入排序中需要移动较远位置的情况;
     * 2.设定一定的gap值,采用跳跃性的分组,分组后对每一组进行插入排序(保证娇小的数值可以尽快排到前面),完成情况1优化;
     * 3.逐渐缩小gap值,重复完成2步骤,及不断优化情况1;
     * 4.当gap达到1,及进行一次普通插入排序,完成即可保证100%元素顺序正确;
     * @param arr
     */
    private static void shellSort(int[] arr) {
        //设定gap值为数组长度的一半,每次完成后再/2;(只是在通过跳跃性的排序,优化极端思路1中的情况)
        //当值达到1时,此时为普通插入排序,可以保证100%完成正确排序;
        for (int gap = arr.length/2; gap > 0; gap/=2) {
            //与普通插入排序思路相同;(插入排序一定要采用移位式交换位置,效率远高于交换式)
            for (int i = gap; i < arr.length; i+=gap) {
                int val=arr[i];
                int j=i-gap;
                while (j>=0&& val<arr[j]){
                    arr[j+gap]=arr[j];
                    j-=gap;
                }
                //利用下标是否变化,进行优化;
                //即:下表未变化,则说明不需移动位置;
                if (j!=i-gap){
                    arr[j+gap]=val;
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值