综合分析一下各个排序算法_这或许是分析10大排序算法最好的一篇文章

本文详细介绍了希尔排序算法,它是插入排序的一种高效改进版本。通过使用不同的间隔进行数据比较和交换,加速了排序过程。文章还提供了具体的动画演示和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

6703f3fc3f242e403b77b456ef0accfc.png

No.4 希尔排序

希尔排序这个名字,来源于它的发明者希尔,也称作“缩小增量排序”,是插入排序的一种更高效的改进版本。

我们知道,插入排序对于大规模的乱序数组的时候效率是比较慢的,因为它每次只能将数据移动一位,希尔排序为了加快插入的速度,让数据移动的时候可以实现跳跃移动,节省了一部分的时间开支。

882bb80448b3be3da681fe22f883973a.gif

希尔排序动画演示

图解希尔排序

待排序数组 10 个数据:

cbf483bc2ac9195f7906cce66f6111cf.png

假设计算出的排序区间为 4 ,那么我们第一次比较应该是用第 5 个数据与第 1 个数据相比较。

9584dfac74543514048c059963ce6aa6.png

调换后的数据为[ 7,2,5,9,8,10,1,15,12,3 ],然后指针右移,第 6 个数据与第 2 个数据相比较。

02573f4049b347b294eed837bf154479.png

指针右移,继续比较。

a35676d81767177bb2874adda1a85fc4.png

8a2e6db337baf82e90ec681da50272a8.png

如果交换数据后,发现减去区间得到的位置还存在数据,那么继续比较,比如下面这张图,12 和 8 相比较,原地不动后,指针从 12 跳到 8 身上,继续减去区间发现前面还有一个下标为 0 的数据 7 ,那么 8 和 7 相比较。

3c8058c4c852b0268f645a6d90d95f72.png

比较完之后的效果是 7,8,12 三个数为有序排列。

b1bae74c8745ceb6cc4af77636f9c5fb.png

当最后一个元素比较完之后,我们会发现大部分值比较大的数据都似乎调整到数组的中后部分了。

假设整个数组比较长的话,比如有 100 个数据,那么我们的区间肯定是四五十,调整后区间再缩小成一二十还会重新调整一轮,直到最后区间缩小为 1,就是真正的排序来了。

2b5fbc165b421ca73d906938326a4675.png

指针右移,继续比较:

9d4ffc4aa67aa6f8f06c5460f3d7c23f.png

重复步骤,即可完成排序,重复的图就不多画了。

我们可以发现,当区间为 1 的时候,它使用的排序方式就是插入排序。

代码实现

public static void sort(int[] arr) {
    int length = arr.length;
    //区间
    int gap = 1;
    while (gap < length) {
        gap = gap * 3 + 1;
    }
    while (gap > 0) {
        for (int i = gap; i < length; i++) {
            int tmp = arr[i];
            int j = i - gap;
            //跨区间排序
            while (j >= 0 && arr[j] > tmp) {
                arr[j + gap] = arr[j];
                j -= gap;
            }
            arr[j + gap] = tmp;
        }
        gap = gap / 3;
    }
}

可能你会问为什么区间要以 gap = gap*3 + 1 去计算,其实最优的区间计算方法是没有答案的,这是一个长期未解决的问题,不过差不多都会取在二分之一到三分之一附近。

感谢你看到了这里,希望看完这篇文章能让你清晰的理解平时最常用的十大排序算法之冒泡排序 关注我下篇文章

长按下方戳我 备注8888

4c5cd186847986d89ffc493bff6ff464.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值