package cn.edu.zjut.Compute; public class 希尔排序 { public static int[] sort(int[] num) { int increment = num.length; int i, j; int middle; do { increment = increment / 3 + 1; for (i = increment; i < num.length; i++) { if (num[i] < num[i - increment]) { middle = num[i]; for (j = i - increment; j >= 0 && num[j] > num[j + increment]; j = j - increment) { num[j + increment] = num[j];// 将大的数赋予后面 } num[j + increment] = middle; } } } while (increment > 1); return num; } public static void main(String[] args) { int[] returnNums = { 1, 6, 7, 20, 2, 5, 9, 50, 22, 33 }; returnNums = sort(returnNums); for (int num : returnNums) { System.out.println(num); } } }
一、算法介绍
这是一个比较难以理解的排序算法之一,如果要理解它的具体步骤的话,可将其与插入排序进行类比;
希尔排序其实借鉴了插入排序的理念,那就是“由前向后”根据比较结果进行插入操作;区别是插入排序是对每个值进行简单地遍历插入,而希尔排序则是利用了“块”进行跨越式的插入!
核心:
(1)将num[i],num[i-increment],num[i-2*increment].......num[i-k*increment](停止条件是(i-(k+1)*increment)<0)这一串数组进行插入排序;
(2)然后,依次循环至i=length;
(3)然后,更换increment,从i=inrement处开始新一轮循环;
(4)更换increment的循环结束的标志是:increment<=1,这样将会结束整个算法!
二、步骤
(1)计算出步长——increment
(2)以步长作为下标,设定i的起始循环(A),循环的步长为1,循环至数组的末尾;
(3)如果num[i]小于num[i-increment],说明下面有可以交换的地方,则进行下面的操作;反之,则返回循环(A);
(4)进行上文所述的“核心”中的步骤(1)的内容,对一个序列进行插入排序,但是步长为increment
(5)返回循环(A)
(6)如果increment>1,则从步骤(1)处重新开始;