zoukankan      html  css  js  c++  java
  • 经典排序算法学习笔记四——希尔排序

    希尔排序

    数据结构 数组
    最差时间复杂度 根据步长序列的不同而不同。已知最好的:O(n*log ^{2}n)
    最优时间复杂度 O(n)
    平均时间复杂度 根据步长序列的不同而不同。
    最差空间复杂度 O(n)

      

    1、算法思想

    1. 先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;
    2. 然后取d2<d1,重复上述分组和排序操作;
    3. 直至di=1,即所有记录放进一个组中排序为止。

    我是栗子,栗子,栗子

     

    假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:

    13 14 94 33 82
    25 59 94 65 23
    45 27 73 25 39
    10
    

    然后我们对每列进行排序:

    10 14 73 25 23
    13 27 94 33 39
    25 59 94 65 82
    45
    

    将上述四行数字,依序接在一起时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:

    10 14 73
    25 23 13
    27 94 33
    39 25 59
    94 65 82
    45
    

    排序之后变为:

    10 14 13
    25 23 33
    27 25 59
    39 65 73
    45 94 82
    94
    

    最后以1步长进行排序(此时就是简单的插入排序了)。

    2、伪代码

    input: an array a of length n with array elements numbered 0 to n − 1
    inc ← round(n/2)
    while inc > 0 do:    
        for i = inc .. n − 1 do:        
            temp ← a[i]        
            j ← i        
            while j ≥ inc and a[j − inc] > temp do:            
                a[j] ← a[j − inc]            
                j ← j − inc        
            a[j] ← temp    
        inc ← round(inc / 2)

    3、实现

    #include <stdio.h>
    #include <stdlib.h>
    void shell_sort(int arr[], int len) {
        int gap, i, j,n=0;
        int temp;
        for (gap = len /2; gap > 0; gap /= 2){
            for (i = gap; i < len; i++) {//gap=1时就是直接插入排序了,首先要理解插入排序
                temp = arr[i];
                for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap)
                    arr[j + gap] = arr[j];
                arr[j + gap] = temp;
            }
            n++;
            printf("
    第%d次sorted:
    ",n);
            printf("gap=%d
    ",gap);
            for (i = 0; i < len; i++)
                printf("%d ", arr[i]);
        }
    }
    int main() {
        int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
        int len = (int) sizeof(arr) / sizeof(*arr);
        int i;
        printf("before shell_sort:
    ");
        for (i = 0; i < len; i++)
            printf("%d ", arr[i]);
        shell_sort(arr, len);
        printf("
    最后结果:
    ");
        for (i = 0; i < len; i++)
            printf("%d ", arr[i]);
        system("pause");
        return 0;
    }
  • 相关阅读:
    fortran imsl 程序库
    使用NET USE将USB端口模拟为LPT1
    Processing鼠标响应(1)
    MATLAB矩阵运算(1)
    Processing中类的定义
    Perl的第二纪
    Processing鼠标响应(2)
    Processing中的图片互动
    gFortran的使用
    用回溯法来产生由0或1组成的2m个二进位串,使该串满足以下要求
  • 原文地址:https://www.cnblogs.com/crystalmoore/p/5930792.html
Copyright © 2011-2022 走看看