【排序算法】希尔排序

1  前言

今天把排序的几个算法过一下,这节我们看一下希尔排序,简单的来说就是多次插入排序,我们看示例。

2  代码示例

/**
 * 希尔排序,也就是多次插入排序
 * 可以参考插入排序,然后外边套一层间隙循环
 * 间隙到最后为1,就跟插入排序一样了
 */
public static void shellSort(int[] arr) {
    for (int gap = arr.length / 2; gap >= 1; gap /= 2) {
        // 外层循环,注意间隙 i=i+gap
        for (int i = gap; i < arr.length; i+=gap) {
            // 升序,arr[i] 当前要插入的值发现比前边的最后一个元素都大说明不需要往前插入,跳过
            if (arr[i-gap] < arr[i]) {
                continue;
            }
            // 记录要进行插入的值
            int temp = arr[i];
            // 记录内层循环的起始位置,从最后一个元素开始遍历
            int j = i-gap;
            // 内层循环,间隙j=j-gap
            for (; j >= 0; j-=gap) {
                // 升序,当发现有比我大的,就往后放
                if (arr[j] > temp) {
                    arr[j+gap] = arr[j];
                    // 持续往后放
                    continue;
                }
                // 发现有比我小的了,停止遍历
                break;
            }
            /**
             * 找到位置了,进行替换 这里为什么 +gap? 参考插入排序最后的+1 这里是间隙
             * 能走到这考虑两种情况:
             * 1、内层循环遍历到索引为 -1时停止的,也就是前边的所有元素都比待插入的大 比如 1 2 5 要插入 0 这是索引为-1 + 1 = 0就是要放入的位置
             * 2、找到一个比待插入的小了 比如 1 2 5 要插入 4 到 2 的时候停止了 这是索引为 1 所以+1 = 2就是要放入待插入的位置
             */
            arr[j+gap] = temp;
        }
        System.out.println("当前间隙:"+ gap + "排序后:" + Arrays.stream(arr).mapToObj(String::valueOf).collect(Collectors.joining(",")));
    }
}
public static void main(String[] args) {
    int[] arr = IntStream.generate(() -> ThreadLocalRandom.current().nextInt(10000)).limit(100).toArray();
    System.out.println("排序前:" + Arrays.stream(arr).mapToObj(String::valueOf).collect(Collectors.joining(",")));
    shellSort(arr);
    System.out.println("排序后:" + Arrays.stream(arr).mapToObj(String::valueOf).collect(Collectors.joining(",")));
}

3  小结

有写的不对的地方,欢迎指正哈。

posted @ 2023-03-14 17:33  酷酷-  阅读(16)  评论(0编辑  收藏  举报