年前沒錢,等發工資。就這麼在公司耗着不敢回家,無聊看了下golang的sort源碼golang
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()進行排序噠ui
貼上源碼實現,這就是經常使用的排序,時間複雜度是O(n*log(n))。。那就是快排、堆排序之類的啦this
// 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的實現。我了個擦。第一次見這麼寫快排的spa
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的,嗯,原來這是兩種計數。本質上木有任何關係,code