排序算法-希尔排序

概述

希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因D.L.Shell于1959年提出而得名。

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  1. 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
  2. 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

该方法实质上是一种分组插入方法

算法过程描述

平均复杂度

希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。

算法稳定性

由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

示例代码

/**
 * 希尔排序
 * @author 吴庆龙
 * Date: 2018/8/6
 * Time: 9:34
 */
public class ShellSort {

    public static void main(String[] args) {
        int[] array = {7,3,2,4,1,8,0,9,5,6};
        sort(array);

        for (int i : array) {
            System.out.print(i + " ");
        }
        System.out.println();
    }

    private static void sort(int[] array) {

        // 定义初始增量
        int increment = array.length / 2;

        // 控制增量
        while (increment > 0) {

            // 控制分组切换
            for (int elemIndex = increment; elemIndex < array.length; elemIndex++) {

                // 已经排好序数组的最后一个元素(如果是普通插入排序,这里这是int k = j - 1)
                int lastSortedElemIndex = elemIndex - increment;
                int key = array[elemIndex]; // 要排序的元素
                for (; lastSortedElemIndex >= 0 && key < array[lastSortedElemIndex] ; lastSortedElemIndex -= increment) {
                    array[lastSortedElemIndex + increment] = array[lastSortedElemIndex];
                }

                // 与插入排序类似
                array[lastSortedElemIndex + increment] = key;
            }

            increment /= 2;
        }

    }

}

希尔排序只是针对插入排序的一个改进,分组之后还是进行的插入排序。

猜你喜欢

转载自www.cnblogs.com/wuqinglong/p/9429041.html