希尔排序

1 实现原理和步骤

     采用插入排序对arr这个数组进行排列,假如位置为0到10000的按照升序排好,将待插入数值a[10001]与a[10000]进行比较,如果a[10001]大于a[10000]时,则将带插入数据的位置为10001,即位置为0到10001已经排好序了。以此类推即可完成整个插入排序。
     问题来了,如果a[10001]的数值特别小呢?就可能要将这个数值从位置10000移动到位置0,大大提高算法的复杂度,因此插入排序在的时间复杂度仍为O(n^2)。
    希尔排序基于插入排序并对上面提到的问题进行改良,大约需要O(n*(log n)^2)时间。原理是先把插入的间隔设为a.length/2, 再不断缩小直到为1,即为普通插入排序,减少小数值出现在右边的概率。


2 完整代码

public class ShellSort {
	/**
	 * 希尔排序 
	 * 基于插入排序进行改良
	 * @param arr
	 */
	public static void shellSort(int[] arr) {
		int gap, temp, i, j;
		for (gap = arr.length / 2; gap > 0; gap /= 2) { // 间隔不断缩小
			for (i = gap; i < arr.length; i++) {
				for (j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap) { // 插入排序,当gap=1时,就是一个普通的插入排序
					temp = arr[j];
					arr[j] = arr[j + gap];
					arr[j + gap] = temp;
				}
			}
//			System.out.print("以间距为" + gap + "进行插入排序,结果为: " + Arrays.toString(arr));
			System.out.print("以间距为" + gap + "进行插入排序,结果为: " );
			display(arr);
		}
	}

	/**
	 * 打印结果
	 */
	public static void display(int[] arr) {
		StringBuilder str = new StringBuilder(); // 字符串拼接
		str.append("[");
		for (int i : arr) {
			str.append(i + ", ");
		}
		str.replace(str.length() - 2, str.length() - 1, "]"); // 不包含起始值
		System.out.println(str.toString());
	}

	/**
	 * 测试
	 * @param args
	 */
	public static void main(String[] args) {
		// 初始化数组
		int[] arr = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
		//  希尔排序
		shellSort(arr);
	}
}		


3 输出结果 



4 参考文献

[1] Robert, Lafore., Java数据结构和算法.第2版 版. 2004: 中国电力出版社.
[2] Sedgewick Robert与Wayne  Kevin., 算法. 2012: 人民邮电出版社.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值