算法学习笔记--希尔排序

本文介绍了一种基于插入排序的快速排序算法——希尔排序。通过将数组转换为h有序数组,并逐步减少h值,最终达到完全排序的目的。文章还提供了一段Java代码实现希尔排序,并讨论了如何选择合适的递增序列来提高算法性能。

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

希尔排序:这是一种基于插入排序的快速的排序算法。
这种排序的主要思想就是:使数组中任意间隔为h的元素都是有序的,这样的数组称为h有序数组

如下图,就是一个h有序数组(h=4):
这里写图片描述

实现希尔排序的方法就是对于每一个h,用插入排序的方式,将h个子数组独立排序,然后逐渐减小h的值,直到h=1。

java代码如下:

/**
 * 希尔排序
 */
public class Shell {

    public static void sort(int[] a){

        int N = a.length;
        int h = 1;
        while(h < N/3){     //  h = 1/2(3^k - 1)  1, 4, 13, 40, 121, 364, 1093, ...
            h = 3*h + 1;    //   选取合适的递增数列可以提高算法性能  这里使用Algorithms一书中推荐的递增数列
        }
        while(h >=1){
            for (int i = h; i < N; i++) {
                for (int j = i; j >= h && (a[j] < a[j-h]); j -= h) {
                    int temp = a[j];
                    a[j] = a[j-h];
                    a[j-h] = temp;
                }
            }
            h = h/3;
        }
    }
}

轨迹图:

这里写图片描述

在上述代码中,使用了序列1/2(3^k-1),从N/3开始逐渐减至1。这种序列称之为递增序列。选择合理的递增序列将提高算法的性能。

特点:
这种排序非常的高效,因为它平衡了子数组的规模和有序性。
和选择排序以及插入排序相比,希尔排序也可用于大型数组,对任意排序的数组表现也很好。





小彩蛋:
最近发现了一个有趣的交换的方法,不增加新的变量来交换a b两个变量的值

a = a ^ b; 
b = a ^ b;  //实际上是(a^b)^b 也就是a异或了b两次,等号右边是a的值
a = a ^ b;  //此时b里面已经是“果汁”,实际上是(a^b)^a,也就是b异或了a两次,是b

所以上述代码中交换可以换成下面这样。

    a[j] = a[j]^a[j-h];
    a[j-h] = a[j]^a[j-h];
    a[j] = a[j]^a[j-h];

这样写立刻显得逼格满满啊 逃)。




这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值