排序_插入排序之希尔排序(缩小增量排序)

概述

希尔(Shell)排序又称为缩小增量排序,它是一种插入排序。它是直接插入排序算法的一种威力加强版。

代码实现

/**
 * 基本思想:
 * 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。
 * 所有距离为d1的倍数的记录放在同一个组中。
 * 先在各组内进行直接插入排序;然后,取第二个增量d2<d1
 * 重复上述的分组和排序,直至所取的增量 =1( < …<d2<d1),
 * 即所有记录放在同一组中进行直接插入排序为止。
 * 
 * 
 * 
 * 
 * @author yeoggc
 *
 */
public class 希尔排序 {

    private void shellSort(int[] array) {

        int gap = array.length / 2;// 初始化gap为数组长度/2

        while (1 <= gap) {// 中止条件是gap<1

            // 对步长为gap的元素进行分组
            // 交替的对每组进行直接插入排序
            for (int i = gap; i < array.length; i++) {

                int temp = array[i];// 待排序的数据
                int j = 0;// 有序区中待比较元素的下标,初始时,从有序区中最后一个元素开始比较起

                // 对步长为 gap 的元素组进行排序
                for (j = i - gap; j >= 0 && temp < array[j]; j = j - gap) {
                    array[j + gap] = array[j];
                }

                array[j + gap] = temp;

            }
            System.out.format("gap = %d:\t", gap);
            printAll(array);
            gap = gap / 2; // 减小增量
        }

    }

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

        // 调用希尔排序方法
        希尔排序 shell = new 希尔排序();
        System.out.print("排序前:\t\t");
        shell.printAll(array);
        shell.shellSort(array);
        System.out.print("排序后:\t\t");
        shell.printAll(array);
    }

    // 打印完整序列
    public void printAll(int[] list) {
        for (int value : list) {
            System.out.print(value + "\t");
        }
        System.out.println();
    }

}

算法分析

这例子希尔排序的步长选择都是从n/2开始,每次再减半,直到最后为1。这并不是最高效的步长选择。

希尔排序是不稳定的:我们知道一次插入排序是稳定的,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,即希尔排序中相等数据可能会交换位置。

希尔排序的平均时间复杂度为O(nlog2n)。

直接插入排序和希尔排序的比较

直接插入排序是稳定的;而希尔排序是不稳定的。
直接插入排序更适合于原始记录基本有序的集合。
希尔排序的比较次数和移动次数都要比直接插入排序少,当N越大时,效果越明显。
在希尔排序中,增量序列gap的取法必须满足:最后一个步长必须是 1 。
直接插入排序也适用于链式存储结构;希尔排序不适用于链式结构

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的...
    Luc_阅读 6,815评论 0 35
  • 概述:排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    每天刷两次牙阅读 9,109评论 0 15
  • 概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部...
    蚁前阅读 10,608评论 0 52
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好...
    依依玖玥阅读 5,036评论 0 2
  • “你就是个混蛋,彻彻底底的大混蛋” 01 她是一个不安分的姑娘,向往仗剑走天涯的生活,她爱跳舞爱唱歌爱吉他爱帅哥,...
    刘哈哈_2b34阅读 2,688评论 0 0

友情链接更多精彩内容