希尔排序
import java.util.Arrays;
public class A006_希尔排序 {
public static void main(String[] args) {
int[] arr = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
shellsort(arr);
System.out.println(Arrays.toString(arr));
}
public static void shellsort(int[] arr) {
for (int i = arr.length / 2; i > 0; i /= 2) {
for (int j = i; j < arr.length; j++) {
int target = arr[j];
int k = j - i;
while (k > -1 && target < arr[k]) {
arr[k + i] = arr[k];
k -= i;
}
arr[k + i] = target;
}
}
}
}
这里用了3层循环来对数组进行希尔排序,希尔排序是将一个数组,以缩小后的增量分段成若干个小数段,进行排序:
1、首先是第一层循环i,i作为增量,首次进入循环,是长度的一半,每次循环除2;
2、第二层循环是j,j是对增量后的每一个坐标进行扫描,所以j的初值是i,但其实,也并不是对每一个坐标进行扫描,而是对增量过后的坐标进行扫描,譬如在此例中,第一次增量i是4,那么j就是从4开始,对4到arr.length的每一个点进行扫描;
3。1、第三层是一个while循环,是用k进行,k的值是j-i,是这一个小段落中的第一个数值的下标,这里插播一段:
这里,我们让target的值等于arr[j],也就是把这个值拿出来,对它前面的每一位进行比较,现在我们接着回到第三层循环:
3.2、当k这个下标没有越界,并且k下标的这个值大于后面那个元素target的话,就进行交换:
交换是将比target大的这个值和k+i下标所处的这个位置进行交换,而k+i这个值就是j,也就是三层循环中,最后交换的那个值(ps:因为如果进入循环的话,k的值就会相应的减少,只要记录一次target,然后不论第三层循环里如何交换,最后结束的时候,都会是k+i这个下标的值,这里可以参考插入排序👇)
import java.util.Arrays;
public class A006_希尔排序 {
public static void main(String[] args) {
int[] arr = { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
sort(arr);
System.out.println(Arrays.toString(arr));
}
public static void sort(int[] arr) {
for (int j = 1; j < arr.length; j++) {
int target = arr[j];
int k = j - 1;
while (k > -1 && target < arr[k]) {
arr[k + 1] = arr[k];
k -= 1;
}
arr[k + 1] = target;
}
}
}
插入排序是将每一个数,与前面一个数进行比较,而希尔排序是有增量的,每一个数,与前一个增量的数进行比较,也就是代码中的k-=i;