分享
  1. 首页
  2. 文章

Go-Sort

u013344915 · · 1244 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

要点

Go的Sort是对一个数据数列进行排序,但不保证stable。——关于stable,请参考数据结构或算法相关介绍。

Interface接口

要使用Sort功能,需要这个数据对象实现sort package中的接口(3个方法):

// A type, typically a collection, that satisfies sort.Interface can be
// sorted by the routines in this package. The methods require that the
// elements of the collection be enumerated by an integer index.
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)
}

这里其实隐含要求这个容器或数据集合是slice类型或Array类型。否则,没法按照索引号取值。

另外,Go的sort要实现的这个接口类似于Java的Comparable接口。C++ STL的sort则要提供一个operator<的binary function。基本思想基本是一致的,只是Go的要求更为严格。

XXXSlice & XXXs

Go的sort包已经为基本数据类型都实现了sort功能,其函数名的最后一个字母是s,表示sort之意。比如:Ints, Float64s, Strings,等等。

对应的,int、float64、string等这些基本数据类型对应的集合类似,则被命名为IntSlice、Float64Slice、StringSlice等。

只需要看源码即可了解前述内容,拷贝如下:

// 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] }
// Ints sorts a slice of ints in increasing order.
func Ints(a []int) { Sort(IntSlice(a)) }

注意这里的Ints(), Sort(), IntSlice()几个函数之间的关系,并对比下面示例中的两种排序步骤。

示例

这里直接取sort_test.go中的部分代码,文件名也要符合test的命名规范,参考Go-Tesing:

package main
import (
 //"fmt"
 "sort"
 "math"
 "testing"
)
var ints = [...]int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
var float64s = [...]float64{74.3, 59.0, math.Inf(1), 238.2, -784.0, 2.3, math.NaN(), math.NaN(), math.Inf(-1), 9845.768, -959.7485, 905, 7.8, 7.8}
var strings = [...]string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"}
func TestSortIntSlice(t *testing.T) {
 data := ints
 a := sort.IntSlice(data[0:])
 sort.Sort(a)
 if !sort.IsSorted(a) {
 t.Errorf("sorted %v", ints)
 t.Errorf(" got %v", data)
 }
}
func TestSortFloat64Slice(t *testing.T) {
 data := float64s
 a := sort.Float64Slice(data[0:])
 sort.Sort(a)
 if !sort.IsSorted(a) {
 t.Errorf("sorted %v", float64s)
 t.Errorf(" got %v", data)
 }
}
func TestSortStringSlice(t *testing.T) {
 data := strings
 a := sort.StringSlice(data[0:])
 sort.Sort(a)
 if !sort.IsSorted(a) {
 t.Errorf("sorted %v", strings)
 t.Errorf(" got %v", data)
 }
}
func TestInts(t *testing.T) {
 data := ints
 sort.Ints(data[0:])
 if !sort.IntsAreSorted(data[0:]) {
 t.Errorf("sorted %v", ints)
 t.Errorf(" got %v", data)
 }
}
func TestFloat64s(t *testing.T) {
 data := float64s
 sort.Float64s(data[0:])
 if !sort.Float64sAreSorted(data[0:]) {
 t.Errorf("sorted %v", float64s)
 t.Errorf(" got %v", data)
 }
}
func TestStrings(t *testing.T) {
 data := strings
 sort.Strings(data[0:])
 if !sort.StringsAreSorted(data[0:]) {
 t.Errorf("sorted %v", strings)
 t.Errorf(" got %v", data)
 }
}

自定义数据类型

package main
import (
 "fmt"
 "sort"
)
type Person struct {
 name string 
 age int 
}
type Persons []Person 
func (ps Persons) Len() int {
 return len(ps)
}
func (ps Persons) Less(i, j int) bool {
 return ps[i].name < ps[j].name
}
func (ps Persons) Swap(i, j int) {
 temp := ps[i]
 ps[i] = ps[j]
 ps[j] = temp
}
func main() {
 // first style
 persons := []Person{
 {"Tom", 5},
 {"Jerry", 6},
 }
 sort.Sort(Persons(persons))
 fmt.Println(persons)
 // second style
 persons2 := Persons{
 {"_Tom", 5},
 {"_Jerry", 6},
 }
 sort.Sort(persons2)
 fmt.Println(persons2)
}

有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:u013344915

查看原文:Go-Sort

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1244 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏