希尔排序

7 篇文章 0 订阅

思想

希尔排序是对简单插入排序算法的一个升级,它的思路就是将原有大量数据记录分割成如干个子序列,再分别对子序列进行插入排序,当整个序列基本有序时,再对全体记录做一次插入排序。

基本有序:就是小的基本在前面,不大不小基本在中间,大的基本在后面。

我们上面提到了将整序列进行分割,那么如何分割将是关键,按顺序分割显然就不合适了,比如我们现在有序列是{9,1,5,8,3,7,4,6,2},现在将它分成三组,{9,1,5} ,{8,3,7}, {4,6,2} ,哪怕将它们各自排序排好了,变成{1,5,9} , {3,7,8},{2,4,6},再合并它们成{1,5,9,3,7,8,2,4,6},此时,这个序列还是杂乱无序,谈不上基本有序。所以我们需要采取“跳跃分割”策略:将相距某个‘增量'的记录组成一个子序列,这样才能保证在子序列内分别进行直接插入排序后得到的结果是基本有序而不是局部有序。

排序过程

以数组 int[] test = {51, 46, 20, 18, 65, 97, 82, 30, 77, 50}为例,这里我选取增量increment = increment / 3;

第一回合:初始增量为test.length /3 = 3



第二回合:增量为1,此时已经是基本有序了,直接进行插入排序达到最终有序

代码

public static void shellSort(int[] test) {
		int j = 0;//记录位置
		//跳跃分割即是定义一个增量,将相距这个增量的记录组成子序列,并分别进行简单插入排序
		for(int increment = test.length / 3;increment > 0;increment = increment/3) {
			for (int i = increment; i < test.length; i++) {
				int temp = test[i];//定义一个哨兵
				for (j = i - increment; j >= 0 && test[j] > temp; j-=increment) {//前面的数大于后面的数
					test[j+increment] = test[j];//往后移动
				}
				test[j+increment] = temp;
			}
			System.out.println(Arrays.toString(test));
		}
	}

复杂度

其时间复杂度为O(n^3/2) ,要好于直接排序的o (n^2 ). 需要注意的是,增量序列的最后一个增量值必须等于1 才行。另外由于记录是跳跃式的移动,希尔排序并不是一种稳定的排序算法。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值