Golang涔?sort 鎺掑簭婧愮爜娴呮瀽
Posted 閾佸尃瀛︾紪绋?/a> Go
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang涔?sort 鎺掑簭婧愮爜娴呮瀽相关的知识,希望对你有一定的参考价值。
闇€姹傛彁娴嬩簡锛屼笉鎯虫懜楸煎害鏃?甯屾湜涓嶈琚悓浜嬬湅鍒梆煒?锛岀湅浜嗕笅sort鍖咃紝浠婂ぉ缁欏ぇ瀹剁畝鍗曞垎浜笅銆?br class="mq-4">
sort鍖呯殑浣跨敤
鍦℅olang涓紩鍏ユ帓搴忔槸鍦╯ort鍖呬笅闈紝浣跨敤鏂规硶鏄細
package main
import "sort"
func main() {
sort.Sort(data)
}
sort.Interface 鎺ュ彛鏂规硶鐨勫畾涔?/strong>
// An implementation of Interface can be sorted by the routines in this package.
// The methods refer to elements of the underlying collection by integer index.
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less reports whether the element with index i
// must 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鍖呭唴閮ㄤ娇鐢ㄣ€俿ort鍖呮彁渚涗簡瀵?鍒囩墖銆乕]float64鍒囩墖鍜?[]string 鍒囩墖鐨勬敮鎸併€?/p>
閫氳繃 do doc 鍙互鐪嬪埌sort鍖呭惈鐨勬柟娉曪細
package sort // import "sort"
Package sort provides primitives for sorting slices and user-defined
collections.
func Float64s(a []float64)
func Float64sAreSorted(a []float64) bool
func Ints(a []int)
func IntsAreSorted(a []int) bool
func IsSorted(data Interface) bool
func Search(n int, f func(int) bool) int
func SearchFloat64s(a []float64, x float64) int
func SearchInts(a []int, x int) int
func SearchStrings(a []string, x string) int
func Slice(slice interface{}, less func(i, j int) bool)
func SliceIsSorted(slice interface{}, less func(i, j int) bool) bool
func SliceStable(slice interface{}, less func(i, j int) bool)
func Sort(data Interface)
func Stable(data Interface)
func Strings(a []string)
func StringsAreSorted(a []string) bool
type Float64Slice []float64
type IntSlice []int
type Interface interface{ ... }
func Reverse(data Interface) Interface
type StringSlice []string
鐩存崳榫欑┐鐪嬫簮鐮?br>
// 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) {
n := data.Len()
quickSort(data, 0, n, maxDepth(n))
}
娉ㄩ噴涓渶鍚庝篃璇存槑浜嗕笉鑳戒繚璇佹帓搴忕殑绋冲畾鎬э紝涔熷氨鏄瀵逛簬鐩稿悓鐨勫厓绱犲苟涓嶈兘淇濊瘉鎺掑簭鍓嶅悗鐨勯『搴忎竴鑷淬€?br>
鐪嬪埌 quickSort 涔嬪悗鎴戣涓哄氨浣跨敤浜嗗揩閫熸帓搴忥紝鍏跺疄涓嶇劧锛佸湪杩欎箣鍓嶅厛鐪嬩笅 maxDepth() 鍑芥暟锛岃繖涓嚱鏁版槸骞插槢鐨勶紵
// maxDepth returns a threshold at which quicksort should switch
// to heapsort. It returns 2*ceil(lg(n+1)).
func maxDepth(n int) int {
var depth int
for i := n; i > 0; i >>= 1 {
depth++
}
return depth * 2
}
杩欎釜鏄垽鏂槸鍚﹀彲浠ヤ娇鐢?鍫嗘帓搴?/strong>銆傝繖涓猟epth 鍊肩敤浜嗗喅瀹氭槸鍚﹂噰鐢ㄥ爢鎺掑簭銆?br>
蹇€熸帓搴弎uickSort()鍑芥暟
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
...
insertionSort(data, a, b)
}
}
sort鍑芥暟浣跨敤鐨?quickSort 鍒嗕负涓ら儴鍒嗭紝褰撻暱搴﹀ぇ浜?2鐨勬椂鍊欙細棣栧厛鍦╩axDepth涓?鐨勬儏鍐典笅锛屼娇鐢ㄥ爢鎺掑簭锛屽氨鏄綋閫掑綊鍒版渶澶ф繁搴︾殑鏃跺€欙紝浣跨敤鍫嗘帓搴忋€傞偅涔堝湪涓嶄负闆剁殑鏃跺€欐垜浠彲浠ョ湅鍑轰娇鐢ㄧ殑灏辨槸蹇€熸帓搴忥紝涓嶈繃鍦ㄥ揩閫熸帓搴忎腑锛屽張杩涜浜嗕竴姝ヤ紭鍖栵紝涔熷氨鏄壘涓綅鏁?doPivot() 杩欎釜鏂规硶銆?/span>
褰撻暱搴﹀皬浜庣瓑浜?2鐨勬椂鍊欎娇鐢?甯屽皵鎺掑簭锛屾垜浠氨鍏堢湅涓嬪笇灏旀帓搴忋€?/p>
鎻掑叆鎺掑簭
Golang涓殑甯屽皵鎺掑簭涓娇鐢ㄧ殑鏄疓ap鍊兼槸6锛屼篃灏辨槸闂撮殧6浣嶄负涓€缁勶紝鍏堣繘琛屾帓搴忥紝鐒跺悗涓嶅悓浜庝竴鑸殑甯屽皵鎺掑簭灏咷ap鍊煎噺鍗婏紝鑰屾槸鐩存帴杩涜鎻掑叆鎺掑簭銆?br>
鍓嶉潰鐨勬枃绔犱篃缁欏ぇ瀹跺垎浜繃鎻掑叆鎺掑簭锛屼粬鐨勬牳蹇冩€濇兂鍦ㄤ簬灏嗘湭鎺掑簭鐨勫厓绱犲湪宸叉帓搴忕殑鍖洪棿涓壘鍒板悎閫傜殑浣嶇疆杩涜鎻掑叆銆?br>
// insertionSort sorts data[a:b] using insertion sort.
func insertionSort(data Interface, a, b int) {
for i := a + 1; i < b; i++ {
for j := i; j > a && data.Less(j, j-1); j-- {
data.Swap(j, j-1)
}
}
}
瀵绘壘涓綅鏁?/strong>
蹇€熸帓搴忕殑鍏抽敭灏辨槸鎵惧埌涓€涓悎閫傜殑涓寸晫鍊硷紝鍚堥€傜殑涓寸晫鍊煎鎺掑簭寰堝叧閿紝濂界殑涓綅鏁板彲浠ュ皢鍏冪礌骞冲潎鐨勫垎涓轰袱閮ㄥ垎锛屾暣浣撳垎鍓茬殑姝ゆ椂鏄庢樉浼氬噺灏戯紝鏈€鍚庤兘澶熼檷浣庤€楄垂鐨勬椂闂淬€?span>
func doPivot(data Interface, lo, hi int) (midlo, midhi int) {
m := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow.
if hi-lo > 40 {
// Tukey's ``Ninther,'' median of three medians of three.
s := (hi - lo) / 8
medianOfThree(data, lo, lo+s, lo+2*s)
medianOfThree(data, m, m-s, m+s)
medianOfThree(data, hi-1, hi-1-s, hi-1-2*s)
}
medianOfThree(data, lo, m, hi-1)
// Invariants are:
// data[lo] = pivot (set up by ChoosePivot)
// data[lo < i < a] < pivot
// data[a <= i < b] <= pivot
// data[b <= i < c] unexamined
// data[c <= i < hi-1] > pivot
// data[hi-1] >= pivot
pivot := lo
a, c := lo+1, hi-1
for ; a < c && data.Less(a, pivot); a++ {
}
b := a
for {
for ; b < c && !data.Less(pivot, b); b++ { // data[b] <= pivot
}
for ; b < c && data.Less(pivot, c-1); c-- { // data[c-1] > pivot
}
if b >= c {
break
}
// data[b] > pivot; data[c-1] <= pivot
data.Swap(b, c-1)
b++
c--
}
// If hi-c<3 then there are duplicates (by property of median of nine).
// Let's be a bit more conservative, and set border to 5.
protect := hi-c < 5
if !protect && hi-c < (hi-lo)/4 {
// Lets test some points for equality to pivot
dups := 0
if !data.Less(pivot, hi-1) { // data[hi-1] = pivot
data.Swap(c, hi-1)
c++
dups++
}
if !data.Less(b-1, pivot) { // data[b-1] = pivot
b--
dups++
}
// m-lo = (hi-lo)/2 > 6
// b-lo > (hi-lo)*3/4-1 > 8
// ==> m < b ==> data[m] <= pivot
if !data.Less(m, pivot) { // data[m] = pivot
data.Swap(m, b-1)
b--
dups++
}
// if at least 2 points are equal to pivot, assume skewed distribution
protect = dups > 1
}
if protect {
// Protect against a lot of duplicates
// Add invariant:
// data[a <= i < b] unexamined
// data[b <= i < c] = pivot
for {
for ; a < b && !data.Less(b-1, pivot); b-- { // data[b] == pivot
}
for ; a < b && data.Less(a, pivot); a++ { // data[a] < pivot
}
if a >= b {
break
}
// data[a] == pivot; data[b-1] < pivot
data.Swap(a, b-1)
a++
b--
}
}
// Swap pivot into middle
data.Swap(pivot, b-1)
return b - 1, c
}
sort鍖呭綋鍓嶆敮鎸佺殑鍐呴儴鏁版嵁绫诲瀷鎺掑簭
IntSlice 鍙?[]int 鎺掑簭
// IntSlice attaches the methods of Interface to []int, sorting in increasing order.
type IntSlice []int
func (p IntSlice) Len() int { return len(p) }
func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Sort is a convenience method.
func (p IntSlice) Sort() { Sort(p) }
闄嶅簭鎺掑簭灏辩敤鍒颁簡reverse()鏂规硶锛?br>
// Reverse returns the reverse order for data.
func Reverse(data Interface) Interface {
return &reverse{data}
}
Float64Slice绫诲瀷鍙奫]float64鎺掑簭
// Float64Slice attaches the methods of Interface to []float64, sorting in increasing order
// (not-a-number values are treated as less than other values).
type Float64Slice []float64
func (p Float64Slice) Len() int { return len(p) }
func (p Float64Slice) Less(i, j int) bool { return p[i] < p[j] || isNaN(p[i]) && !isNaN(p[j]) }
func (p Float64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// isNaN is a copy of math.IsNaN to avoid a dependency on the math package.
func isNaN(f float64) bool {
return f != f
}
StringSlice绫诲瀷鍙奫]string鎺掑簭
// StringSlice attaches the methods of Interface to []string, sorting in increasing order.
type StringSlice []string
func (p StringSlice) Len() int { return len(p) }
func (p StringSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p StringSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Sort is a convenience method.
func (p StringSlice) Sort() { Sort(p) }
瀛︿範鎺掑簭婧愮爜鍙楃泭鍖祬锛岃瀛︿範鍜岃繘姝ョ殑绌洪棿澶ぇ浜嗭紒杈圭晫鏉′欢鏄唬鐮佸畨鍏ㄧ殑鏈€澶т繚闅滐紒
娆㈣繋鏉ュ柗锝?/p>
榧撳姳涓嬪姞涓叧娉ㄥ惂锛?/span>
鍔犳补锛?/span>涓嶄粎鑷繁锝炶繕鏈変綘锝?/span>
以上是关于Golang涔?sort 鎺掑簭婧愮爜娴呮瀽的主要内容,如果未能解决你的问题,请参考以下文章
shell涓夊墤瀹箣awk(鍖呮嫭sort鎺掑簭鍜寀niq宸ュ叿)
鐮佸啘鎵嬭 | Spring WebFlux瀹炴垬浠ュ強鍘熺悊娴呮瀽
Objective-C 鍐呭瓨绠$悊娴呮瀽涓庡惊鐜己寮曠敤涓句緥