分享
  1. 首页
  2. 文章

模仿 Go Sort 排序接口实现的自定义排序

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

Go 语言对于类型的要求非常严格,导致我们无法声明一个 interface 类型的切片对其排序。所以这里模仿 Go 的 sort 排序扩展包,实现对某个特定类型排序的方法。

查看完整代码,点击这里

Interface 接口

若要实现一个自定义的排序,就要实现 sort 包的排序接口。要排序的集合必须包含一个数字类型的索引,所以待排序的数据类型只能是数组或者切片。

// 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)
}

自定义排序的结构体

我们将对所有的学生进行排序,学生包含他的姓名以及成绩,排序的规则是按照学习的成绩排序。

type Student struct {
 Name string
 Score int
}
type Students []Student

实现排序的接口

func (s Students) Len() int {
 return len(s)
}
// 在比较的方法中,定义排序的规则
func (s Students) Less(i, j int) bool {
 if s[i].Score < s[j].Score {
 return true
 } else if s[i].Score > s[j].Score {
 return false
 } else {
 return s[i].Name < s[i].Name
 }
}
func (s Students) Swap(i, j int) {
 temp := s[i]
 s[i] = s[j]
 s[j] = temp
}

实现排序逻辑

Go 提供了基于快排实现的排序方法,这里为了体验为什么 Go 这么定义 Interface 接口,我使用了选择排序的方法代替 Go 的快排。

func Sort(s sort.Interface) {
 length := s.Len()
 for i := 0; i < length; i++ {
 minIndex := i
 for j := i + 1; j < length; j++ {
 if s.Less(j, i) {
 minIndex = j
 }
 }
 s.Swap(minIndex, i)
 }
}

在这个排序中,我使用了接口中定义的三个方法: Len(),Less(),Swap()。最重要的还是 Less(),没有它程序就不知道如何去比较两个未知元素的大小。

重写输出

为了更好的输出学生的信息,重写学生的字符串输出格式

func (s Student) String() string {
 return fmt.Sprintf("Student: %s %v", s.Name, s.Score)
}

测试输出

通过以下程序测试我们的排序算法

func main() {
 arr := []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
 SelectionSort(arr, len(arr))
 fmt.Println(arr)
 students := student.Students{}
 students = append(students, student.Student{"D", 90})
 students = append(students, student.Student{"C", 100})
 students = append(students, student.Student{"B", 95})
 students = append(students, student.Student{"A", 95})
 Sort(students)
 for _, student := range students {
 fmt.Println(student)
 }
}

以下是输出结果:

[1 2 3 4 5 6 7 8 9 10]
Student: D 90
Student: A 95
Student: B 95
Student: C 100

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

本文来自:Segmentfault

感谢作者:Donne

查看原文:模仿 Go Sort 排序接口实现的自定义排序

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

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

用户登录

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

今日阅读排行

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

一周阅读排行

    加载中

关注我

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

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

给该专栏投稿 写篇新文章

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

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