Interface 接口(你没看错,就叫Interface)
该接口是sort包的核心接口,sort包通过该接口进行排序
type Interface interface {
Len() int // 返回元素个数
Less(i, j int) bool // 比较
Swap(i, j int) // 交换
}
复制代码
排序
Ints()、Float64s()、Strings()
这几个方法使用实现了对应类型的Interface接口的类对slice进行包装,这样我们就不需要自己实现Interface接口了。
package main
import (
"fmt"
"sort"
)
func main() {
arr := []int{1, 3, 5, 3, 4, 2, 1, 2, 3, 6, 8, 3}
sort.Ints(arr)
fmt.Println(arr) // [1 1 2 2 3 3 3 3 4 5 6 8]
}
复制代码
Sort()
这个方法需要实现了Interface接口的参数,因此我们需要自己实现Interface接口,比如:
package main
import (
"fmt"
"sort"
)
type IntSlice []int
func (x IntSlice) Len() int { return len(x) }
func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
func (x IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func main() {
arr := IntSlice{1, 3, 5, 3, 4, 2, 1, 2, 3, 6, 8, 3}
sort.Sort(arr)
fmt.Println(arr) // [1 1 2 2 3 3 3 3 4 5 6 8]
}
复制代码
Slice()
这个方法可以只实现Interface接口的Less()方法,第一个参数是slice类型:
package main
import (
"fmt"
"sort"
)
func main() {
arr := []int{1, 3, 5, 3, 4, 2, 1, 2, 3, 6, 8, 3}
sort.Slice(arr, func(i, j int) bool {
return arr[i] < arr[j]
})
fmt.Println(arr) // [1 1 2 2 3 3 3 3 4 5 6 8]
}
复制代码
Reverse()
反转,比如:
package main
import (
"fmt"
"sort"
)
type IntSlice []int
func (x IntSlice) Len() int { return len(x) }
func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
func (x IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func main() {
arr := IntSlice{1, 3, 5, 3, 4, 2, 1, 2, 3, 6, 8, 3}
sort.Sort(arr)
fmt.Println(arr) // [1 1 2 2 3 3 3 3 4 5 6 8]
sort.Sort(sort.Reverse(arr))
fmt.Println(arr) // [8 6 5 4 3 3 3 3 2 2 1 1]
}
复制代码
内部实现就算把Less()的ij换一下位置:
type reverse struct {
Interface
}
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
func Reverse(data Interface) Interface {
return &reverse{data}
}
复制代码
Stable()、SliceStable()
保证排序是稳定的,也就是相同值得元素的原始位置不会改变:
package main
import (
"fmt"
"sort"
)
type Item struct {
Index int
Value int
}
func main() {
arr := []Item{{1, 1}, {2, 3}, {3, 5}, {4, 3}, {5, 4}, {6, 1}, {7, 1}, {8, 1}}
fmt.Println(arr) // [{1 1} {2 3} {3 5} {4 3} {5 4} {6 1} {7 1} {8 1}]
arrCopy := make([]Item, len(arr))
copy(arrCopy, arr)
// 不稳定排序
sort.Slice(arr, func(i, j int) bool {
return arr[i].Value < arr[j].Value
})
// 本来在后边的[8 1]跑到了[6 1] [7 1]前面,[4 3]跑到了[2 3]前面
fmt.Println(arr) // [{1 1} {8 1} {6 1} {7 1} {4 3} {2 3} {5 4} {3 5}]
// 稳定排序
sort.SliceStable(arrCopy, func(i, j int) bool {
return arrCopy[i].Value < arrCopy[j].Value
})
fmt.Println(arrCopy) // [{1 1} {6 1} {7 1} {8 1} {2 3} {4 3} {5 4} {3 5}]
}
复制代码
是否已经排序
共有IntsAreSorted()、、Float64sAreSorted()、StringsAreSorted()、IsSorted()、SliceIsSorted()5个方法
前三个不需要自己实现Interface接口,IsSorted()则需要自己实现Interface()接口,SliceIsSorted()可以只实现Less()方法
package main
import (
"fmt"
"sort"
)
func main() {
arr := []int{1, 3, 5, 3, 4, 2, 1, 2, 3, 6, 8, 3}
fmt.Println(sort.IntsAreSorted(arr)) // false
sort.Ints(arr)
fmt.Println(sort.IntsAreSorted(arr)) // true
}
复制代码
搜索
功能是搜索已经排序好的列表某个元素应该插入的下标
共有Search()、SearchInts()、SearchFloat64s()、SearchStrings()4个方法
第一个Search()需要实现Interface接口,后面3个不需要实现Interface接口
package main
import (
"fmt"
"sort"
)
func main() {
arr := []int{1, 3, 5, 3, 4, 2, 1, 2, 3, 6, 8, 3}
sort.Ints(arr)
fmt.Println(arr) // [1 1 2 2 3 3 3 3 4 5 6 8]
fmt.Println(sort.SearchInts(arr, 3)) // 4
fmt.Println(sort.SearchInts(arr, 7)) // 11
}
复制代码