算法(四)希尔排序

排序原理

希尔排序主要是将数组中的元素按照一定的步长进行分组,步长相同的元素被分为一组,改组是逻辑上的分组,并不改变元素所在数组中的位置,分组以后在按照插入排序对每个组进行排序,当每个组排序完成后,在将步长递减,当步长依次递减到1时,该数组就已经是排好序的了。

时间复杂度

希尔排序是不稳定排序,当进行大量的实验以后,希尔排序的平均时间复杂度为O(n1.3)。

排序代码

package com.alg.sort;

public class ShellSort {
    /**
     * 希尔排序算法:从插入排序延伸过来的
     */
    public void shellSort(int[] arr, int a, int n) {
        /**
         * 设置增量步长为数组的一半,该排序算法最复杂的就是该步长的确定
         */
        for (int i = arr.length / 2; i > 0; i /= 2) {
            /**
             * 确定步长的两个元素
             * 以10为例,步长为5,那么第一次循环的元素的下标为j=5,j++一直遍历到数组的尾部
             */
            for (int j = i; j < arr.length; j++) {
                //将下标为5的元素复制一份,该元素是分组中最右边的元素
                int e = arr[j];
                //记录该元素需要放置的位置。
                int index;

                /**
                 *分组,以步长5为距离,将元素逻辑上分组,改分组是逻辑上的,元素的位置 本身不变的。
                 * 原理:步长5为距离的分组中最右边的元素减去步长,那么该元素就是该分组中
                 * 最左边的元素。这样我们来计算数组最右边的元素是否小于最左边的元素,如果为true,
                 * 就将最左的元素复制给最右边的元素,然后把事先复制出来的最右的元素复制到最左边的元素,
                 * 请注意:当循环结束的时候,index由于执行了 index-=i了,这个时候index就成负数,只有
                 * 再次将步长加回来,才是真正最左边的下标位置。
                 */
                for (index = j - i; index >= 0 && arr[index] > e; index -= i) {
                    arr[index + i] = arr[index];
                }
                arr[index + i] = e;
            }
        }
    }
}

发布了94 篇原创文章 · 获赞 55 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/Suubyy/article/details/100100335