先取一个小于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,