希尔排序java实现

思路:
比如,我们有1000个数据项需要排序,利用h=3*h+1产生的间隔序列为:1,4,13,40,12,121,364,1093,3280…0000000000
364就是第一轮排序的步长,接下来依次是121,12…
1.确定第一次排序的步长h
2.排序
—while(结束条件步长为零)
--------for
---------------对从第一对到第h对拆分的数组排序
---------------------插入排序
--------计算下一轮的步长:(h-1)/3

代码

public void shellSort(int arr[]){
		
		int length = arr.length,h=1;//h为步长
		while(3*h+1<length){
			h = 3*h+1;
		}
		int previous = 0,temp=0;
		while(h>0){
			for(int i=0;i<h;i++){
				int targetIndex = i+h;
				
				while(targetIndex<length){
					temp = arr[targetIndex];
					previous = targetIndex - h;//前一个数组下标
					while(previous>=0&&arr[previous]>temp){
						arr[previous+h] = arr[previous];//把大的数依次往后挪
						previous = previous-h;//多减了一个h
					}
					arr[previous+h] = temp;
					targetIndex = targetIndex + h;
					
				}
				
			}
			h = (h-1)/3;//计算下一轮步长,当然这样写乘过来除过去,浪费了
			
		}
	}

优化版 (不是我的思路,书上的)

public void shellSort2(int arr[]){
		int i,h,target,z,pre,increment[] = new int[20];
		/*	
		 * increment存储了步长数据
		 * i为步长的数组下标,即i也控制了排序几轮
		 * h为当前一轮排序的步长
		 * z为当前一轮排序的组数
		 * taget为插入排序待插入数据
		 * pre为这组数据前1~n的数组下标
		 * */
		for(h = 1,i = 0;h < arr.length;i++){
			increment[i] = h;
			h = 3*h + 1; 
		}
		for(i--;i >= 0;i--){//控制排多少轮
			h = increment[i];
			for(z = h;z < 2*h;z++){//排每轮的h个组数据
				for(target = z;target < arr.length;){//排每一组数据(插入排序)
					int temp = arr[target];
					pre = target-h;
					while(pre>=0&&arr[pre]>temp){
						arr[pre+h] = arr[pre];
						pre -= h;
					}
					arr[pre+h] = temp;
					target += h;
				}
			}
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值