Hill sort is an improved version of insertion sort.
It can be regarded as a kind of grouping insertion sort, and grouping changes are affected by the group tail index iii and group stepstep steps t e p control, after dividing into groups, perform insertion sort on the elements of each group.
code show as below:
public class Main {
public static void main(String[] args) {
int[] arr = {3, 3, 5, 6, 2, 1};
System.out.print("排序前:");
arrPrint(arr);
ShellSort(arr);
System.out.print("排序后:");
arrPrint(arr);
}
// 希尔排序
// 希尔排序是插入排序的改进版,意为将数组arr按照递减的步长step分组,
// 同组的元素距离相邻一个step的长度,小组的尾索引记为i,每组分别使用插入排序,
// 每次排序完步长step将按照减半来递减,构成新分组,再每组分别进行插入排序,
// 以此循环下去,直至step=1,分组到最后只剩1组,小组尾索引i不断右移,即遍历完数组arr
//
// 实例中step将分别等于3,1。(想看过程可以利用arrPrint函数将中间过程打印)
// 第一层for循环将step初始化为数组长度的一半,后循环减半,
// 第二层for循环,锚定分组后每组的尾索引为i=j+step。由于同组元素距离为一个step,
// 所以同组的元素可以通过j循环减step获得。
private static void ShellSort(int[] arr) {
int len = arr.length;
for (int step = len / 2; step >= 1; step /= 2) {
for (int i = step; i < len; i++) {
GroupInsertSort(arr, step, i);
}
}
}
// (分组)插入排序
// 还记得原来插入排序中i是从1开始的,就相当于分组后的i是从step开始的。
// 遍历数为arr[i]=temp,这也就是待排序元素。
// j = i - step为同组的i前一个元素索引,根据插入排序算法,
// 如果j = i - step索引的元素arr[i]大于i索引的元素temp,
// 则在同组内用while循环将大于temp的左边元素全部右移。
// 注意指针要移动一个step的距离。
private static void GroupInsertSort(int[] arr, int step, int i) {
int temp = arr[i];
int j = i - step;
while (j >= 0 && arr[j] > temp) {
arr[j + step] = arr[j];
j -= step;
}
if (j != i - step)
arr[j + step] = temp;
}
// 辅助函数:将int[] 打印出来
private static void arrPrint(int[] arr) {
StringBuilder str = new StringBuilder();
str.append("[");
for (int v : arr) {
str.append(v + ", ");
}
str.delete(str.length() - 2, str.length());
str.append("]");
System.out.println(str.toString());
}
}
The animated demonstration of the example is as follows: