java排序算法(希尔Shell)

本文详细解析希尔排序算法的原理及其优化步骤,通过实例代码展示常见错误及解决方法,帮助开发者掌握该算法并避免常见陷阱。

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

希尔排序(Shell Sort)也称为递减增量排序,是插入排序的一种更高效的改进版本,希尔排序是不稳定的排序算法

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
  • 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位
希尔排序其实需要确定步长,也就是增量的大小,这个方法我常见的有两种,一种是直接每次都是d=d/2;还有一种就是用Math.ceil(d1/2)方法是向上取整运算。我习惯于直接是d=d/2。

首先想一下希尔排序在编写代码的时候思路:我任务分为2步:

1、确定步长,对步长进行循环,通过步长找到所谓的虚拟数组。

2、把虚拟数组用直接插入排序就OK了。

昨天的时候想起了希尔排序就随手写了一个,在运行的时候发现了很多的错误。

	public static int[] shellSort(int[] arr){
		int n = arr.length;
		int d=n;
		while(true){
			d = d/2;
			for(int i=0; i<d; i++){
				for(int j=i+d; j<n; j+=d){
					int tmp = arr[j];
					int k=j-d;
					for( ; k>=0; k-=d){
						if(tmp< arr[k]){
							arr[k+d] = arr[k];
						}
					}
					arr[k+d] = tmp;
				}
			}
		if(d==1)
			break;
		}
		return arr;
	}
运行后会发现出错了,就以9, 8, 7, 6, 5, 4, 3, 2, 1, 0为例

当d=5的时候运行完是没有问题的结果变为4, 3, 2, 1, 0, 9, 8, 7, 6,  5

当d=2的时候此时虚拟数组是[4, 2, 0, 8, 6]和[3, 1, 9, 7, 5]最内层for循环对 4, 2, 0没问题变为0, 2, 4但是当读取到8的时候,此时的内循环无误,只是不进行交换,但是k却一直在减小,最后arr[k+d] = tmp的时候 k+d的值是0,把8赋给了数组第一个。导致出了问题,后来修改了一下。代码如下:

	public static int[] shellSort(int[] arr){
		int n = arr.length;
		int d=n;
		while(true){
			d = d/2;
			for(int i=0; i<d; i++){
				for(int j=i+d; j<n; j+=d){
					int tmp = arr[j];
					int k=j-d;
					for( ; k>=0&&tmp<arr[k]; k-=d){
							arr[k+d] = arr[k];
					}
					arr[k+d] = tmp;
				}
			}
		if(d==1)
			break;
		}
		return arr;
	}

运行就OK了。

在代码量没达到一定的水平的时候,不能仅仅感觉思想理解了就OK了,要自己去实现一下,还是有很多小细节问题需要注意。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值