Golang 數(shù)據(jù)排序

sort.Interface 接口

這個(gè)接口是 sort 包的核心,它有3個(gè)方法。這是 Golang 很酷的一個(gè)特性,只要數(shù)據(jù)類型滿足 sort.Interface 接口,就可以用sort包的函數(shù)進(jìn)行排序。

// 一個(gè)滿足sort.Interface接口的(集合)類型可以被本包的函數(shù)進(jìn)行排序。
// 方法要求集合中的元素可以被整數(shù)索引。
type Interface interface {
    // Len方法返回集合中的元素個(gè)數(shù)
    Len() int
    // Less方法報(bào)告索引i的元素是否比索引j的元素小
    Less(i, j int) bool
    // Swap方法交換索引i和j的兩個(gè)元素
    Swap(i, j int)
}

Example1

package main

import (
    "fmt"
    "sort"
)

//自定義一個(gè)類型
type ints []int

func (s ints) Len() int           { return len(s) }
func (s ints) Less(i, j int) bool { return s[i] < s[j] }
func (s ints) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func main() {
    nums := []int{9, 8, 5, 4, 7, 6, 3, 0, 1, 2}

    sort.Sort(ints(nums)) //進(jìn)行排序
    fmt.Println(nums)
}

Output: [0 1 2 3 4 5 6 7 8 9]

Example2

package main

import (
    "fmt"
    "sort"
)

type Person struct {
    Name string
    Age  int
}

type Persons []Person

func (s Persons) Len() int           { return len(s) }
func (s Persons) Less(i, j int) bool { return s[i].Age < s[j].Age }
func (s Persons) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func main() {
    p := []Person{Person{"Lily", 20}, Person{"Bing", 18}, Person{"Tom", 23}, Person{"Vivy", 16}, Person{"John", 18}}

    sort.Sort(sort.Reverse(Persons(p))) //sort.Reverse 生成遞減序列
    fmt.Println(p)
}

Output: [{Tom 23} {Lily 20} {Bing 18} {John 18} {Vivy 16}]

sort 包內(nèi)置的排序方法

So easy ! 看了2個(gè)例子你應(yīng)該明白了吧!

方法 說(shuō)明
func Sort(data Interface) 遞增排序,不能保證排序的穩(wěn)定性,即不保證相等元素的相對(duì)次序不變。用的是快速排序算法。
func Stable(data Interface) 遞增排序,保證排序的穩(wěn)定性,相等元素的相對(duì)次序不變。用的是插入排序算法。
func IsSorted(data Interface) bool 判斷data是否已經(jīng)被遞增排序
func Reverse(data Interface) Interface 對(duì)該接口排序可生成遞減序列
func Ints(a []int) 將 []int 排序?yàn)檫f增順序
func IntsAreSorted(a []int) bool 檢查 []int 是否已排序?yàn)檫f增順序
func Float64s(a []float64) 將 []float64 排序?yàn)檫f增順序
func Float64sAreSorted(a []float64) bool 檢查 []float64 是否已排序?yàn)檫f增順序
func Strings(a []string) 將 []string 排序?yàn)檫f增順序
func StringsAreSorted(a []string) bool 檢查 []string 是否已排序?yàn)檫f增順序

Example:

s := []int{5, 2, 6, 3, 1, 4} // unsorted
sort.Ints(s)
fmt.Println(s)

Output: [1 2 3 4 5 6]

使用自定義排序算法

package main

import (
    "fmt"
    "sort"
)

//bubbleSort 冒泡排序
func bubbleSort(data sort.Interface) {
    r := data.Len() - 1
    for i := 0; i < r; i++ {
        for j := r; j > i; j-- {
            if data.Less(j, j-1) {
                data.Swap(j, j-1)
            }
        }
    }
}

//insertSort 插入排序
func insertSort(data sort.Interface) {
    r := data.Len() - 1
    for i := 1; i <= r; i++ {
        for j := i; j > 0 && data.Less(j, j-1); j-- {
            data.Swap(j, j-1)
        }
    }
}

//selectSort 選擇排序
func selectSort(data sort.Interface) {
    r := data.Len() - 1
    for i := 0; i < r; i++ {
        min := i
        for j := i + 1; j <= r; j++ {
            if data.Less(j, min) {
                min = j
            }
        }
        data.Swap(i, min)
    }
}

func main() {
    nums := []int{9, 8, 5, 4, 7, 6, 3, 0, 1, 2}
    ints := sort.IntSlice(nums) //IntSlice給[]int添加方法以滿足Interface接口,以便排序?yàn)檫f增序列。

    bubbleSort(ints) //使用冒泡排序
    fmt.Println(ints)
}

output: [0 1 2 3 4 5 6 7 8 9]

搜索

搜索和排序是2兄弟,搜索是從已經(jīng)排序的數(shù)據(jù)中返回?cái)?shù)據(jù)的位置。

方法 說(shuō)明
func SearchInts(a []int, x int) int SearchInts在遞增順序的a中搜索x,返回x的索引。如果查找不到,返回值是x應(yīng)該插入a的位置(以保證a的遞增順序),返回值可以是len(a)。是Search函數(shù)函數(shù)的包裝。
func SearchFloat64s(a []float64, x float64) int 同上,只是數(shù)據(jù)類型不同
func SearchStrings(a []string, x string) int 同上,只是數(shù)據(jù)類型不同
func Search(n int, f func(int) bool) int 采用二分法搜索找到[0, n)區(qū)間內(nèi)最小的滿足f(i)==true的值i。返回找到的索引i,如果沒有符合要求的索引,則返回 n。

Example1:[]int 搜索

package main

import (
    "fmt"
    "sort"
)

func main() {
    data := sort.IntSlice{9, 5, 3, 25, 1, 5, 64, 45, 21, 48, 55}
    data.Sort() // 等價(jià)于調(diào)用 sort.Sort,搜索前需要先排序。
    fmt.Println(data)

    x := 5
    i := data.Search(x) // 等價(jià)于調(diào)用 sort.SearchInts
    fmt.Printf("%v is present at data[%d]\n", x, i)
}

output:
[1 3 5 5 9 21 25 45 48 55 64]
5 is present at data[2]

Example2: []struct 搜索

package main

import (
    "fmt"
    "sort"
)

type Person struct {
    Name string
    Age  int
}

type Persons []Person

func (s Persons) Len() int           { return len(s) }
func (s Persons) Less(i, j int) bool { return s[i].Age < s[j].Age }
func (s Persons) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func main() {
    p := []Person{Person{"Lily", 20}, Person{"Bing", 18}, Person{"Tom", 23}, Person{"Vivy", 16}, Person{"John", 18}}
    sort.Sort(sort.Reverse(Persons(p))) //sort.Reverse 生成遞減序列
    fmt.Println(p)

    x := 18
    i := sort.Search(len(p), func(i int) bool {
        //如果使用 p[i].Age == x,則找不到索引時(shí)返回的是n,而不是列表應(yīng)該插入的位置,會(huì)破壞列表順序。
        //在升序列表中使用 p[i].Age >= x,則找不到索引時(shí)返回接近x的位置,以保證列表的遞增順序
        //在降序列表中使用 p[i].Age <= x,則找不到索引時(shí)返回接近x的位置,以保證列表的遞減順序
        return p[i].Age <= x
    })
    fmt.Println(i)
}

output:
[{Tom 23} {Lily 20} {Bing 18} {John 18} {Vivy 16}]
2


參考:https://my.oschina.net/evilunix/blog/370676

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,551評(píng)論 19 139
  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,912評(píng)論 0 33
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 7,325評(píng)論 0 17
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,671評(píng)論 18 399
  • 而你撐傘擁我入懷中 ——我的一個(gè)道姑朋友(改 編) 那日,她上山采藥。下山途中,天空布滿金絲,綿綿細(xì)...
    舊顏er閱讀 1,732評(píng)論 9 55

友情鏈接更多精彩內(nèi)容