golang 写个希尔排序

追风骚年 · · 491 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

希尔排序非常的牛,听说是第一个打破时间复杂度我 n² 的算法,通过一个区间不断缩小,由远及近,最终达到有序状态,也可以称为加强版的分组插入排序。

算法描述

  • 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
  • 按增量序列个数k,对序列进行k 趟排序;
  • 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的
    长度。

先回顾一下插入排序

func insertionSort(arr []int) {
    for i := 1; i < len(arr); i++ {
        for j := i; j > 0 && arr[j] < arr[j-1]; j-- {
            arr[j], arr[j-1] = arr[j-1], arr[j]
        }
    }
}

希尔排序的精髓在于增量的选择,教科书上一般都是不断除以 2,最后达到1,这样做的问题是,奇数位和偶数位的数字始终不能比较。增量选择也是这个排序的魅力所在,看多很多资料给到的是 3x+1为一个合适的分组状态,所以我们先选择 3x+1 ,更多分组可以参照参考文档。

func shellSort(arr []int) {
    h := 1
    for h < len(arr)/3 { 
        h = 3*h + 1
    }

    for h >= 1 {
        for i := h; i < len(arr); i++ {
            for j := i; j >= h && arr[j] < arr[j-h]; j -= h {
                arr[j], arr[j-h] = arr[j-h], arr[j]
            }
        }
        h /= 3
    }
}

希尔排序相对于插入排序来说,外层套了一个递减变量,
希尔排序的时间复杂度为 o(n^k) (k=1.3~2.0),具体 1.3 怎么算出来的,很玄学没找到地方列出推导过程,2 是因为如果整体逆序的情况下的最差情况。

参考文档


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:追风骚年

查看原文:golang 写个希尔排序

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

491 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传