希尔排序(缩小增量排序)
点击查看代码
package Sort;
import java.util.*;
public class 希尔排序增量 {
public static void main(String[] args) {
//三个循环控制
int array[] = {2,9,8,6,10,12,7};
int n = array.length;
int inc;//增量
int key;//中间变量
int i,j;
for(inc = n/2; inc > 0; inc/=2) {
for( i = inc; i < n; i++) {//i=inc相当于i=1;
for(j = i; j >=inc ; j-=inc) {//已排跟待排的间隔是inc;j是>=inc,而不是跟插入一样>0,确保j-inc存在。
if(array[j] < array[j-inc]) {
key = array[j];
array[j] = array[j-inc];
array[j-inc] = key;
}
else break;
}
}
System.out.println(Arrays.toString(array));
}
System.out.println(Arrays.toString(array));
}
}
点击查看代码
package Sort;
import java.util.Arrays;
public class ShellSort {
public static void main(String[] args) {
int array[] = {2, 9, 8, 6, 10, 12, 7};
shellSort(array);
System.out.println(Arrays.toString(array));
}
public static void shellSort(int[] array) {
int n = array.length;
int inc; // 增量
// 初始增量设置为数组长度的一半,之后每次减半,直到增量为1
for (inc = n / 2; inc > 0; inc /= 2) {
// 对于每个增量inc,进行希尔排序的子过程
for (int i = inc; i < n; i++) {
int temp = array[i]; // 暂存当前要插入的元素
int j;
// 将array[i]插入到已经排序的array[0...i-inc]中
// 注意这里j的起始值是i-inc,因为我们假设从i-inc到0的元素已经是以inc为间隔的有序序列
for (j = i; j >= inc && array[j - inc] > temp; j -= inc) {
array[j] = array[j - inc]; // 记录后移
}
array[j] = temp; // 插入正确位置
}
}
}
}
包和类声明:代码位于Sort包中,类名为ShellSort,这更清晰地反映了类的用途。
主方法:main方法用于测试希尔排序算法。它创建了一个整数数组array,调用shellSort方法对数组进行排序,并打印排序后的数组。
希尔排序方法:shellSort方法接受一个整数数组作为参数,并对其进行排序。
初始化增量:增量inc初始化为数组长度的一半。这是希尔排序的起始间隔,用于将数组元素分组为更远的间隔进行比较和交换。
外层循环:外层循环控制增量的减小,每次循环都将增量减半,直到增量为1。当增量为1时,算法退化为普通的插入排序,但此时数组已经接近有序,因此效率很高。
内层循环(插入排序过程):对于每个增量inc,内层循环遍历数组(从inc开始,因为前面的元素在之前的增量下已经排序),将当前元素插入到以inc为间隔的有序序列中。这通过比较和交换元素来实现,类似于插入排序中的元素插入过程,但比较和交换的间隔是inc。
这种优化后的希尔排序算法通过减少初始时元素之间的比较和交换距离,以及逐步减小增量来使数组更加有序,从而提高了排序的效率。