一、希尔排序
/** * 希尔排序: * 某些情况下,直接插入排序的效率很低。比如有一个升序数组, * 然后我们插入一个比这个数组最小值还小的数, * 这也就意味着需要和每个数都进行一次比较。插入排序对已经排好序的数组来说效率很高。 * 所以我们可以先构建一个相对有序的数组,然后再做插入排序。 * 希尔排序把序列按一定步长分组,对每组分别进行插入排序。随着步长减少,直到1,算法结束。 * 希尔排序又叫缩小增量排序。 * 一般来说,初次取数组长度的一半作为步长,以后每次减半,直到为1。 */
public static void shellSort(Integer[] arr) {
//gap为步长,每次减少到原来的一半,直到减为1
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
//对每一组数据都进行直接插入排序,一共有gap组
for (int i = 0; i < gap; i++) {
//对本组数据进行直接插入排序
for (int j = i + gap; j < arr.length; j += gap) {
//如果arr[j]<arr[j-gap],则寻找arr[j]的位置,将这个位置的数据后移
if (arr[j] < arr[j - gap]) {
int k;
int temp = arr[j];
for (k = j - gap; k >= 0 && arr[k] > temp; k -= gap) {
arr[k + gap] = arr[k];
}
//把最后一个不满足条件的后一个位置赋给temp
arr[k + gap] = temp;
}
}
}
}
}
注意事项:
1.步长gap一般从数组的一半开始取,每次减半,直到为1
2.gap为多少,那么就会有多少个分组
3.对每个分组进行直接插入排序
二、全部代码
public class _4_ShellSort {
public static void main(String[] args) {
Integer[] arr = {3, 5, 1, 7, 2, 3, 4, 8};
shellSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void shellSort(Integer[] arr) {
//gap为步长,每次减少到原来的一半,直到减为1
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
//对每一组数据都进行直接插入排序,一共有gap组
for (int i = 0; i < gap; i++) {
//对本组数据进行直接插入排序
for (int j = i + gap; j < arr.length; j += gap) {
//如果arr[j]<arr[j-gap],则寻找arr[j]的位置,将这个位置的数据后移
if (arr[j] < arr[j - gap]) {
int k;
int temp = arr[j];
for (k = j - gap; k >= 0 && arr[k] > temp; k -= gap) {
arr[k + gap] = arr[k];
}
//把最后一个不满足条件的后一个位置赋给temp
arr[k + gap] = temp;
}
}
}
}
}
}