关于希尔排序的介绍、复杂度等这里就不介绍了,直接看该算法的思路,每步都干什么写在了注释里,可以打开代码中注释掉的打印部分代码来查看具体的排序过程
排序方法:
public class HillSort {
public static int[] shellSort(int[] array) {
// //打印说明
// System.out.println("数组元素[索引];halfLen为间隔;i、j为数组索引");
//数组长度
int len = array.length;
//以数组一半长度为间隔开始比较对应位置的数,每次循环该间隔都除以2
//如:8个数,间隔为4,比较0-4,1-5,2-6,3-7索引位置的数
//第二轮循环间隔为2,比较0-2,1-3,2-4,3-5,4-6,5-7
//。。。
for (int halfLen = len / 2; halfLen > 0; halfLen /= 2) {
//取halfLen位置i的值与对应的i-halfLen位置j的值比较,值小的放在左边
for (int i = halfLen; i < len; i++) {
// //打印外循环过程
// if ((i - halfLen) == 0) {
// System.out.println();
// }
// for (int k = 0; k < len; k++) {
// System.out.print(array[k] + "[" + k + "] ");
// }
// System.out.print("| ");
// System.out.print("halfLen=" + halfLen + "; 比较位置:" + " i=" + i + " j=" + (i - halfLen));
// System.out.println();
//暂存该索引处对应的值,交换位置用
int temp = array[i];
int j;
//除了索引i与索引(i-halfLen)比较外,索引i与索引(i-halfLen倍数)也比较
//注意循环条件
for (j = i - halfLen; j >= 0 && array[j] > temp; j -= halfLen) {
//交换位置用
array[j + halfLen] = array[j];
// //打印索引i与索引(i-halfLen倍数)比较过程
// if (j - halfLen >= 0) {
// //打印用,临时变为最终结果
// array[j + halfLen] = temp;
// for (int k = 0; k < len; k++) {
// System.out.print(array[k] + "["+k+"] ");
// }
// System.out.print("| ");
// System.out.print("halfLen=" + halfLen + "; 比较位置:" + " i=" + i + " j=" +(j - halfLen ));
// System.out.println();
// //打印结束,恢复原来数组以保证正常执行排序
// array[j + halfLen] = array[j];
// }
}
//交换位置用
array[j + halfLen] = temp;
}
}
return array;
}
}
测试方法:
public class TestSort {
int[] array = {8, 1, 6, 7, 3, 5, 2, 4};
//希尔排序
@Test
public void hillSort() {
int[] sort = HillSort.shellSort(array);
//输出最终结果
System.out.println("排序结果:");
for (int i : sort) {
System.out.print(i+ " ");
}
}
}