年前没钱,等发工资。就这么在公司耗着不敢回家,无聊看了下golang的sort源码

type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with
// index i should sort before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}

只有实现这个接口才可以调用sort.Sort()进行排序哒

贴上源码实现,这就是常用的排序,时间复杂度是O(n*log(n))。。那就是快排、堆排序之类的啦

// Sort sorts data.
// It makes one call to data.Len to determine n, and O(n*log(n)) calls to
// data.Less and data.Swap. The sort is not guaranteed to be stable.
func Sort(data Interface) {
// Switch to heapsort if depth of 2*ceil(lg(n+1)) is reached.
n := data.Len()
maxDepth := 0
for i := n; i > 0; i >>= 1 {
maxDepth++
}
maxDepth *= 2
quickSort(data, 0, n, maxDepth)
}

它用的是quicksort。然而,它还有个maxDepth。让我很恼火。这不多余的变量么。然后就去看quicksort的实现。我了个擦。第一次见这么写快排的

func quickSort(data Interface, a, b, maxDepth int) {
for b-a > 12 { // Use ShellSort for slices <= 12 elements
if maxDepth == 0 {
heapSort(data, a, b)
return
}
maxDepth--
mlo, mhi := doPivot(data, a, b)
// Avoiding recursion on the larger subproblem guarantees
// a stack depth of at most lg(b-a).
if mlo-a < b-mhi {
quickSort(data, a, mlo, maxDepth)
a = mhi // i.e., quickSort(data, mhi, b)
} else {
quickSort(data, mhi, b, maxDepth)
b = mlo // i.e., quickSort(data, a, mlo)
}
}
if b-a > 1 {
// Do ShellSort pass with gap 6
// It could be written in this simplified form cause b-a <= 12
for i := a + 6; i < b; i++ {
if data.Less(i, i-6) {
data.Swap(i, i-6)
}
}
insertionSort(data, a, b)
}
}

解释下变量,a:起始位置,b:结束位置 ,maxDepth:深度,这个参数在Sort()中计算好了,是通过右移算出来的。so。这就是所有元素构建的完全二叉树的深度哈。这狗日的要在快排里用heapsort了,算完了理论上构建的完全二叉树的深度后。它maxDepth *= 2 来了这一手,让我抽根烟冷静冷静。它得到的是这些元素组成的最深的二叉树的深度,高手啊。然后带quicksort的代码中来瞅瞅。当需要排序的元素大于12个的时候。。快排啊。就是这里还判断了深度是否为0,一头雾水啊,这是在搞什么?这个for循环有两个退出条件,1:b-a<12了。2:maxDepth==0。so,为嘛会有maxDepth==0啊。此时的待排序元素可是大于12的,嗯,原来这是两种计数。本质上木有任何关系,

golang的sort研究的更多相关文章

  1. Golang学习 - sort 包

    ------------------------------------------------------------ // 满足 Interface 接口的类型可以被本包的函数进行排序. type ...

  2. VS Code对Golang的基准测试研究

    初心 想要在VS Code比较方便的调试Go代码的性能,了解到基准测试对此很有帮助,但默认VS Code执行 Go 的基准测试默认的benchtime为1秒,但测试性能时需要设置为更多秒 办法 在VS ...

  3. golang(10)interface应用和复习

    原文链接 http://www.limerence2017.com/2019/10/11/golang15/ interface 意义? golang 为什么要创造interface这种机制呢?我个人 ...

  4. golang拾遗:为什么我们需要泛型

    从golang诞生起是否应该添加泛型支持就是一个热度未曾消减的议题.泛型的支持者们认为没有泛型的语言是不完整的,而泛型的反对者们则认为接口足以取代泛型,增加泛型只会徒增语言的复杂度.双方各执己见,争执 ...

  5. golang sort包使用

    https://studygolang.com/static/pkgdoc/pkg/sort.htm#StringSlice.Search package main import ( "fm ...

  6. golang 自定义类型的排序sort

    sort包中提供了很多排序算法,对自定义类型进行排序时,只需要实现sort的Interface即可,包括: func Len() int {... } func Swap(i, j int) {... ...

  7. ? 这是个很好的问题。Go 当前的 GC 显然做了一些额外的工作,但它也跟其他的工作并行执行,所以在具有备用 CPU 的系统上,Go 正在作出合理的选择。请看 https://golang.org/issue/17969 结束语(Closing notes) 通过研究 Go 垃圾收集器,我能够理解 Go GC 当前结构的背景以及它如何克服它的弱点。Go发展得非常快。如果你对 Go感兴趣,最好继

    ? 这是个很好的问题.Go 当前的 GC 显然做了一些额外的工作,但它也跟其他的工作并行执行,所以在具有备用 CPU 的系统上,Go 正在作出合理的选择.请看 https://golang.org/i ...

  8. golang container heap&sort

    go语言也自己的容器数据结构.主要有list.heap和ring package main import ( "container/heap" "fmt" &q ...

  9. golang for循环里面创建协程问题的研究

    原本想在一个for里面创建10个协程,这些协程顺序拿到for的递增变量,把这10个递增变量都打印出来.但事与愿违,于是做实验,查书,思考,写出以下记录. golang里,在for循环里面起协程,如下代 ...

随机推荐

  1. 互评Final版本——二次元梦之队——“I Do”

    基于NABCD评论作品,及改进建议 1.根据(不限于)NABCD评论作品的选题; (1)N(Need,需求) 当今的许多科技大佬从少年时代就已经开始了自己的编程生涯,我国许多人也意识到了拥有编程能力的 ...

  2. oracle union

    union 取并集,去重不仅去掉两个集合之间的重复,也会去掉集合的自重复

  3. java计算器实验报告

    一.实验目的 1.熟悉java图形用户界面的设计原理和程序结构 2.能设计复核问题要求的图形用户界面程序 3.熟悉java awt和swing的组合 4.掌握常用组建的事件借口 5.会应用awt和sw ...

  4. ci test

    下载ci 版本 3.1.9 下载地址 https://www.codeigniter.com/ 怎么查看CI的版本信息?想看某个项目中使用的CI具体是哪个版本,怎么查看?system\core\cod ...

  5. MySQL的order by时区分大小写

    Mysql 查询区分大小写 mysql查询默认是不区分大小写的 如: select * from some_table where str=‘abc'; select * from some_tabl ...

  6. delphi制作登陆窗体

    delphi登陆窗体的制作,就我知道的,可以有两种方法,一种是在工程文件中实现登陆窗体的动态调用,另一种就是在主窗体的OnCreate事件中动态创建登陆窗体,两种方法都需要将主窗体设置为Auto-cr ...

  7. 深入理解es6的promise

    一.promise入门 1. Promise对象是什么 回调函数的另一种原生实现,比之前回调函数的写法机构清晰,功能强大, 2.以前回调这么写 function a(fn){ let h = 1; s ...

  8. [国家集训队]middle

    [国家集训队]middle 题目 解法 开\(n\)颗线段树,将第\(i\)颗线段树中大于等于第\(i\)小的数权值赋为1,其他的则为-1,对于每个区间维护一个区间和,最大前缀和,最大后缀和. 然后二 ...

  9. Linux中dpkg工具update-alternatives实现符号链接软件版本的切换(转)

    一.功能作用 update-alternatives是dpkg的实用工具,用来维护系统命令的符号链接,以决定系统默认使用什么命令. 在Debian系统中,我们可能会同时安装有很多功能类似的程序和可选配 ...

  10. 51nod 1295 XOR key (可持久化Trie树)

    1295 XOR key  题目来源: HackerRank 基准时间限制:1.5 秒 空间限制:262144 KB 分值: 160 难度:6级算法题   给出一个长度为N的正整数数组A,再给出Q个查 ...