站長資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        go語言中的排序講解

        go語言中的排序講解

        go語言的排序思路和 c 和 c++ 有些差別。 c 默認是對數(shù)組進行排序, c++ 是對一個序列進行排序, go 則更寬泛一些,待排序的可以是任何對象, 雖然很多情況下是一個 slice (分片, 類似于數(shù)組),或是包含 slice 的一個對象。

        排序(接口)的三個要素:

        待排序元素個數(shù) n ;

        第 i 和第 j 個元素的比較函數(shù) cmp ;

        第 i 和 第 j 個元素的交換 swap ;

        乍一看條件 3 是多余的, c 和 c++ 都不提供 swap 。 c 的 qsort 的用法: qsort(data, n, sizeof(int), cmp_int); data 是起始地址, n 是元素個數(shù), sizeof(int) 是每個元素的大小, cmp_int 是一個比較兩個 int 的函數(shù)。

        c++ 的 sort 的用法: sort(data, data+n, cmp_int); data 是第一個元素的位置, data+n 是最后一個元素的下一個位置, cmp_int 是比較函數(shù)。

        基本類型 int 、 float64 和 string 的排序

        升序排序

        對于 int 、 float64 和 string 數(shù)組或是分片的排序, go 分別提供了 sort.Ints() 、 sort.Float64s() 和 sort.Strings() 函數(shù), 默認都是從小到大排序。(沒有 sort.Float32s() 函數(shù), me 頗有點奇怪。)

        package main   import (     "fmt"     "sort" )   func main() {     intList := [] int {2, 4, 3, 5, 7, 6, 9, 8, 1, 0}     float8List := [] float64 {4.2, 5.9, 12.3, 10.0, 50.4, 99.9, 31.4, 27.81828, 3.14}     // float4List := [] float32 {4.2, 5.9, 12.3, 10.0, 50.4, 99.9, 31.4, 27.81828, 3.14}    // no function : sort.Float32s     stringList := [] string {"a", "c", "b", "d", "f", "i", "z", "x", "w", "y"}         sort.Ints(intList)     sort.Float64s(float8List)     sort.Strings(stringList)         fmt.Printf("%vn%vn%vn", intList, float8List, stringList)   }

        降序排序

        int 、 float64 和 string 都有默認的升序排序函數(shù), 現(xiàn)在問題是如果降序如何 ? 有其他語言編程經(jīng)驗的人都知道,只需要交換 cmp 的比較法則就可以了, go 的實現(xiàn)是類似的,然而又有所不同。

        go 中對某個 Type 的對象 obj 排序, 可以使用 sort.Sort(obj) 即可,就是需要對 Type 類型綁定三個方法 : Len() 求長度、 Less(i,j) 比較第 i 和 第 j 個元素大小的函數(shù)、 Swap(i,j) 交換第 i 和第 j 個元素的函數(shù)。

        sort 包下的三個類型 IntSlice 、 Float64Slice 、 StringSlice 分別實現(xiàn)了這三個方法, 對應排序的是 [] int 、 [] float64 和 [] string。如果期望逆序排序, 只需要將對應的 Less 函數(shù)簡單修改一下即可。

        go 的 sort 包可以使用 sort.Reverse(slice) 來調(diào)換 slice.Interface.Less ,也就是比較函數(shù),所以, int 、 float64 和 string 的逆序排序函數(shù)可以這么寫:

        package main   import (     "fmt"     "sort" )   func main() {     intList := [] int {2, 4, 3, 5, 7, 6, 9, 8, 1, 0}     float8List := [] float64 {4.2, 5.9, 12.3, 10.0, 50.4, 99.9, 31.4, 27.81828, 3.14}     stringList := [] string {"a", "c", "b", "d", "f", "i", "z", "x", "w", "y"}         sort.Sort(sort.Reverse(sort.IntSlice(intList)))     sort.Sort(sort.Reverse(sort.Float64Slice(float8List)))     sort.Sort(sort.Reverse(sort.StringSlice(stringList)))         fmt.Printf("%vn%vn%vn", intList, float8List, stringList) }

        深入理解排序

        sort 包中有一個 sort.Interface 接口,該接口有三個方法 Len() 、 Less(i,j) 和 Swap(i,j) 。 通用排序函數(shù) sort.Sort 可以排序任何實現(xiàn)了 sort.Inferface 接口的對象(變量)。

        對于 [] int 、[] float64 和 [] string 除了使用特殊指定的函數(shù)外,還可以使用改裝過的類型 IntSclice 、 Float64Slice 和 StringSlice , 然后直接調(diào)用它們對應的 Sort() 方法;因為這三種類型也實現(xiàn)了 sort.Interface 接口, 所以可以通過 sort.Reverse 來轉(zhuǎn)換這三種類型的 Interface.Less 方法來實現(xiàn)逆向排序, 這就是前面最后一個排序的使用。

        下面使用了一個自定義(用戶定義)的 Reverse 結(jié)構(gòu)體, 而不是 sort.Reverse 函數(shù), 來實現(xiàn)逆向排序。

        package main   import (     "fmt"     "sort" )   // 自定義的 Reverse 類型 type Reverse struct {     sort.Interface    // 這樣, Reverse 可以接納任何實現(xiàn)了 sort.Interface (包括 Len, Less, Swap 三個方法) 的對象 }   // Reverse 只是將其中的 Inferface.Less 的順序?qū)φ{(diào)了一下 func (r Reverse) Less(i, j int) bool {     return r.Interface.Less(j, i) }   func main() {     ints := []int{5, 2, 6, 3, 1, 4}     // 未排序       sort.Ints(ints)                                     // 特殊排序函數(shù), 升序     fmt.Println("after sort by Ints:t", ints)  // [1 2 3 4 5 6]       doubles := []float64{2.3, 3.2, 6.7, 10.9, 5.4, 1.8}       sort.Float64s(doubles)                                      // float64 排序版本 1     fmt.Println("after sort by Float64s:t", doubles)   // [1.8 2.3 3.2 5.4 6.7 10.9]       strings := []string{"hello", "good", "students", "morning", "people", "world"}     sort.Strings(strings)     fmt.Println("after sort by Strings:t", strings)    // [good hello mornig people students world]       ipos := sort.SearchInts(ints, -1)    // int 搜索     fmt.Printf("pos of 5 is %d thn", ipos)     // 并不總是正確呀 ! (搜索不是重點)       dpos := sort.SearchFloat64s(doubles, 20.1)    // float64 搜索     fmt.Printf("pos of 5.0 is %d thn", dpos)   // 并不總是正確呀 !       fmt.Printf("doubles is asc ? %vn", sort.Float64sAreSorted(doubles))       doubles = []float64{3.5, 4.2, 8.9, 100.98, 20.14, 79.32}     // sort.Sort(sort.Float64Slice(doubles))    // float64 排序方法 2     // fmt.Println("after sort by Sort:t", doubles)    // [3.5 4.2 8.9 20.14 79.32 100.98]     (sort.Float64Slice(doubles)).Sort()         // float64 排序方法 3     fmt.Println("after sort by Sort:t", doubles)       // [3.5 4.2 8.9 20.14 79.32 100.98]       sort.Sort(Reverse{sort.Float64Slice(doubles)})    // float64 逆序排序     fmt.Println("after sort by Reversed Sort:t", doubles)      // [100.98 79.32 20.14 8.9 4.2 3.5] }

        sort.Ints / sort.Float64s / sort.Strings 分別來對整型/浮點型/字符串型分片或是叫做片段,或是不嚴格滴說是數(shù)組,進行排序。然后是有個測試是否有序的函數(shù)。還有分別對應的 search 函數(shù),不過,發(fā)現(xiàn)搜索函數(shù)只能定位到如果存在的話的位置,不存在的話,位置就是不對的。

        關(guān)于一般的數(shù)組排序,程序中顯示了,有 3 種方法!目前提供的三種類型 int,float64 和 string 呈現(xiàn)對稱的,也就是你有的,對應的我也有。

        關(guān)于翻轉(zhuǎn)排序或是逆向排序,就是用個翻轉(zhuǎn)結(jié)構(gòu)體,重寫 Less 函數(shù)即可。上面的 Reverse 是個通用的結(jié)構(gòu)體。

        上面說了那么多, 只是對基本類型進行排序, 該到說說 struct 結(jié)構(gòu)體類型的排序的時候了, 實際中這個用得到的會

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 欧美激情精品久久久久久久| 国产精品无码日韩欧| 老司机亚洲精品影院| 国产99视频精品专区| 精品国产一区二区三区无码 | 精品国产乱码久久久久久浪潮| 国产suv精品一区二区33| 最新国产精品拍自在线播放| 精品免费久久久久国产一区| 久久精品国产秦先生| 91精品国产乱码久久久久久| 亚洲国产精品无码久久| 无码精品蜜桃一区二区三区WW| 国产精品自产拍在线观看花钱看 | 无码国内精品人妻少妇| 香蕉国产精品麻豆亚洲欧美日韩精品自拍欧美v国 | 国产精品尹人在线观看| 秋霞午夜鲁丝片午夜精品久| 99在线精品视频在线观看| 欧美日韩人妻精品一区二区在线 | 欧美亚洲成人精品| 国产伦精品一区二区三区视频猫咪| 久久国产亚洲精品麻豆| 3D动漫精品啪啪一区二区下载| 精品无码人妻夜人多侵犯18 | 精品水蜜桃久久久久久久| 国产免费伦精品一区二区三区| 91精品国产综合久久四虎久久无码一级| 99re这里只有精品6| 国产精品亚洲日韩欧美色窝窝色欲| 久久精品无码专区免费青青| 久久精品人人做人人爽电影蜜月| 日韩精品少妇无码受不了| 亚洲国产精品va在线播放| 无码人妻精品一区二区三区99仓本| 午夜天堂精品久久久久| 欧美成人精品高清在线观看| 欧美肥屁VIDEOSSEX精品| 国产AV无码专区亚洲精品 | 亚洲中文精品久久久久久不卡| 亚洲国产精品一区第二页|