在希尔排序中,取增量(步长)的智慧

思想

希尔排序大概就是,选一组递减的整数作为增量序列(也就是步长)。最小的增量必须为1:DM>DM−1>...>D1=1DM>DM−1>...>D1=1

  • 先用第一个增量把数组分为若干个子数组,每个子数组中的元素下标距离等于增量;
  • 然后对每个子数组进行一次插入排序
  • 再使用第二个增量,继续同样的操作,直到增量序列里的增量都使用过一次。
    (增量为1时,就是对整个数组进行一次插入排序)

图解

看图更容易理解吧:

                                                                (慕课的浙大数据结构)  

性能

希尔排序快不快主要取决于我们怎么取“增量序列”,原始希尔排序的取法就是:DM=⌊N/2⌋,Dk=⌊Dk+1/2⌋DM=⌊N/2⌋,Dk=⌊Dk+1/2⌋
此增量序列也称为Shell增量序列
原始希尔排序最坏的时间复杂度为O(n2)

代码实现

(最原始的实现有四重循环,不太简洁,下面的实现是优化后的,通过改变初始索引淡化了分组的那一层循环)

    public static void shellSort(int[] arr) {
		int h = arr.length>>1;

		while(h >= 1){
			for(int i = h; i < arr.length; i++){
				int temp = arr[i];
				while (i >= h &&temp < arr[i-h]) {
					arr[i] = arr[i-h];
					i-=h;
				}
				arr[i] = temp;
			}
			h = h>>1;
		}
	}

优化

希尔排序的优化主要是针对增量序列的优化

                                                                (慕课的浙大数据结构)  

上面这个例子做了很多次毫无意义的循环

所以有人就发现了,如果增量之间不互质的话,那有些情况就不管用了。

于是有些大佬们就整出了下面这些增量序列:Hibbard增量序列Knuth增量序列Sedgewick增量序列等等

当用这些序列作为增量的时候就可以改善这种情况,并且减少希尔算法一定的时间复杂度

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值