zoukankan      html  css  js  c++  java
  • 希尔排序

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

    • 时间复杂度不确定,看具体实现,依赖于增量序列函数,本文实现的时间复杂度为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
    }
    
  • 相关阅读:
    PHP 实现 一致性哈希 算法(转的)
    一致性 hash 算法
    分布式设计与开发---宏观概述
    Lvs+keepalived+nginx+php的session 保持的算法
    从零搭建Web网站
    Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
    哪个线程执行 CompletableFuture’s tasks 和 callbacks?
    HTTP 用户认证
    java 发送 HTTP 请求
    Http basic Auth 认证方式帮助类
  • 原文地址:https://www.cnblogs.com/qijinzhi/p/shell_sort.html
Copyright © 2011-2022 走看看