java的希尔排序shell-sort

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量

  

=1(

  

<

  

…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

按照某种间隔,分很多组,每个组进行插入排序,

 * 回顾插入排序:就是当前值和前面已经排序的一组数对比,找到当前值可以插入的合适位置,这里和前边对比,不需要交换位置, 只是把前面比当前值大的都向后移动,相当于往前依次腾出一个位置,最后把当前值放到这个合适的位置

<strong>package 希尔排序;
/*
 * 按照某种间隔,分很多组,每个组进行插入排序,
 * 回顾插入排序:就是当前值和前面已经排序的一组数对比,找到当前值可以插入的合适位置,这里和前边对比,不需要交换位置,
 * 只是把前面比当前值大的都向后移动,相当于往前依次腾出一个位置,最后把当前值放到这个合适的位置
 */

import java.nio.charset.MalformedInputException;

public class ShellSort {
	public static void sort(int[] arr) {
		/*
		 * 首先判断一个间隔的最大值,我们的依据是别人规定的比较好的一种分割方式,
		 * 间隔初始值为1,然后一次执行下边maxn=3maxn+1,maxn取不大于数组长度的最大值,
		 * maxn的取值为1、4、13、40、、、、、、依次下去,比如我们数组大小为5, 那么我们maxn就取4
		 */

		int maxn = 1;
		while (3 * maxn + 1 >= arr.length) {
			maxn = 3 * maxn + 1;
		}
		while (maxn > 0) {// 这个wile循环用于不断缩小比较的间隔
			int temp=0;
			for ( int i = maxn; i < arr.length; i++) {
				/*
				 * 这里初始位置为最大间隔位置(该位置是刚好和第一个(下标为0的)位置元素对比
				 * ,然后一个一个往后,直到目标点到达数组最后一个才退出循环。
				 * 比如:第当前值arr[i]会和当第i-maxn元素对比,如果arr[i-maxn]大,
				 * 就把arr[i-maxn]的值向后移动maxn个位置,然后继续把当前值和arr[i-maxn-maxn]、、、、、、
				 */
				temp = arr[i];//这里设置了一个中间值,而不是直接用arr[i],因为temp,到了缩短间隔的时候,会int temp=0;置零;相当于只是一个依次while循环里面的临时变量
				int j = i;// 我下边的要用到j,但是这个j的初始值是i
				while (j >= maxn && arr[j - maxn] > temp) {
					// 把j-maxn的值和当前值对比,(当前值是后边一个即是:或者temp),要是当前值较大,就把j-maxn的值向后移动一次,
					// 然后再把当前值和j-maxn-maxn比较,依次下去
					arr[j] = arr[j - maxn];
					// 交换过后,我还要继续向前,当前位置元素j依次和j=j-maxn位置元素进行比对
					j = j - maxn;
				}
				// 到这里已经找到了这个小组中,当前值应该到达的位置,然后将当前值放到这个位置
				arr[j] = temp;
			}
			// 退出这个循环过后,需要缩小间隔,maxn=3*maxn-1;
			maxn = (maxn - 1) / 3;
		}
	}

	// 来一个测试代码
	public static void main(String[] args) {
		int arr[] = new int[5];

		arr[0] = 22;
		arr[1] = 33;
		arr[2] = 99;
		arr[3] = 66;
		arr[4] = 60;
		for (int k = 0; k < arr.length; k++) {
			System.out.print(arr[k]+",");
		}
		System.out.println();
		sort(arr);
		for (int k = 0; k < arr.length; k++) {
			System.out.print(arr[k]+",");
		}

	}

}</strong>

控制台输出:

22,33,99,66,60,

22,33,60,66,99,

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值