• 希尔排序


    希尔排序是插入排序的一种,又叫缩小增量排序,也是对直接插入排序的一种优化,下面是插入排序的一些特征:

    • 时间复杂度不确定,看具体实现,依赖于增量序列函数,本文实现的时间复杂度为O(n^2),若步长选取为 2^k+1, ..., 5, 3, 1 其时间复杂度为 O(n1.5),当n在某个特定范围时,有些实现可以达到O(n1.3)
    • 空间复杂度,最好最坏平均都为:O(1)
    • 是否稳定:不稳定

    每次排序,数据都会变得更加有序

    希尔排序的基本思想:先将待排序表每隔一定距离取一个数据,形成一个子表,整个表化为许多子表,然后对每个子表分别进行直接插入排序,步长越来越小,最后为1时,对表整个表进行一次直接插入排序。

    有人可能会觉得这不是简单问题复杂化吗?并不是,因为直接插入排序算法适用于基本有序数据量不大的排序表,适用于的意思就是更快,所以可以利用这两个特性对直接插入排序进行优化,将一个子表变成多个子表,就是在缩小数据量,子表有序后,整个表就更加有序了。

    子表选取例子:原表L(1,2,3,4,5,6,7,8,9)有九个元素,步长 dk 取 9/2 即 4,得到 4 个子表 L1(1,5,9), L2(2,6), L(3,7), L(4,8)

    下面是一种希尔排序的代码,增量选取为 n/2, n/4, ..., 2, 1:

    /**
    * arr 数组首地址
    * len 数组长度
    */
    void shell_sort(int *arr, int len)
    {
        int i, j;
        int dk;     // 记录步长
        for (dk=len/2; dk>=1; dk>>=1) { // 步长变化
            for (i=dk; i<len; i++) {
                if (arr[i] < arr[i-dk]) {
                    int temp = arr[i];
                    for (j=i-dk; j>=0 && temp<arr[j]; j-=dk)
                        arr[j+dk] = arr[j];
                    arr[j+dk] = temp;
                }//if
            }//for
        }//for
    }
    

    测试代码,可直接复制后编译执行:

    #include <stdio.h>
    
    void show(int *arr, int len);
    void insert_sort(int *arr, int len);
    
    int main()
    {
        int len = 7;
        int arr[] = {7, 10, 11, 9, -8, 2, 27};
        insert_sort(arr, len);
        show(arr, len);
        return 0;
    }
    
    /**
    * arr 数组首地址
    * len 数组长度
    */
    void show(int *arr, int len)
    {
        int i;
        for (i=0; i<len; i++) {
            printf("%4d", arr[i]);
        }
        printf("
    ");
    }
    
    /**
    * arr 数组首地址
    * len 数组长度
    */
    void shell_sort(int *arr, int len)
    {
        int i, j;
        int dk;     // 记录步长
        for (dk=len/2; dk>=1; dk>>=1) { // 步长变化
            for (i=dk; i<len; i++) {
                if (arr[i] < arr[i-dk]) {
                    int temp = arr[i];
                    for (j=i-dk; j>=0 && temp<arr[j]; j-=dk)
                        arr[j+dk] = arr[j];
                    arr[j+dk] = temp;
                }//if
            }//for
        }//for
    }
    
  • 相关阅读:
    yarn 国内加速,修改镜像源
    Gradle Wrapper 介绍
    使用 Gradle 快速创建 Java 项目
    Gradle 安装
    gradle 国内加速,修改镜像源
    maven 国内加速,修改镜像源
    java如何对map进行排序详解(map集合的使用)
    Java8 Collections.sort()及Arrays.sort()中Lambda表达式及增强版Comparator的使用
    给定字符串正整数,进行排序并返回排序后字符串
    Linux学习118 nginx与php结合实现web网站及优化
  • 原文地址:https://www.cnblogs.com/qijinzhi/p/shell_sort.html
Copyright © 2020-2023  润新知