排序操作是很多程序经常使用的操作。尽管一个简短的快排程序只要二三十行代码就可以搞定,但是一个健壮的实现需要更多的代码,并且我们不希望每次我们需要的时候都重写或者拷贝这些代码。幸运的是,Go内置的sort包中提供了根据一些排序函数来对任何序列进行排序的功能。

排序整数、浮点数和字符串切片

对于[]int, []float, []string这种元素类型是基础类型的切片使用sort包提供的下面几个函数进行排序。

  • sort.Ints
  • sort.Floats
  • sort.Strings
s := []int{4, 2, 3, 1}
sort.Ints(s)
fmt.Println(s) // 输出[1 2 3 4]

使用自定义比较器排序

  • 使用sort.Slice函数排序,它使用一个用户提供的函数来对序列进行排序,函数类型为func(i, j int) bool,其中参数i, j是序列中的索引。
  • sort.SliceStable在排序切片时会保留相等元素的原始顺序。
  • 上面两个函数让我们可以排序结构体切片(order by struct field value)。
family := []struct {Name stringAge  int
}{{"Alice", 23},{"David", 2},{"Eve", 2},{"Bob", 25},
}// 用 age 排序,年龄相等的元素保持原始顺序
sort.SliceStable(family, func(i, j int) bool {return family[i].Age < family[j].Age
})
fmt.Println(family) // [{David 2} {Eve 2} {Alice 23} {Bob 25}]

排序任意数据结构

  • 使用sort.Sort或者sort.Stable函数。
  • 他们可以排序实现了sort.Interface接口的任意类型

一个内置的排序算法需要知道三个东西:序列的长度,表示两个元素比较的结果,一种交换两个元素的方式;这就是sort.Interface的三个方法:

type Interface interface {Len() intLess(i, j int) bool // i, j 是元素的索引Swap(i, j int)
}

还是以上面的结构体切片为例子,我们为切片类型自定义一个类型名,然后在自定义的类型上实现 srot.Interface 接口

type Person struct {Name stringAge  int
}// ByAge 通过对age排序实现了sort.Interface接口
type ByAge []Personfunc (a ByAge) Len() int           { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }func main() {family := []Person{{"David", 2},{"Alice", 23},{"Eve", 2},{"Bob", 25},}sort.Sort(ByAge(family))fmt.Println(family) // [{David, 2} {Eve 2} {Alice 23} {Bob 25}]
}

实现了sort.Interface的具体类型不一定是切片类型;下面的customSort是一个结构体类型。

type customSort struct {p    []*Personless func(x, y *Person) bool
}func (x customSort) Len() int {len(x.p)}
func (x customSort) Less(i, j int) bool { return x.less(x.p[i], x.p[j]) }
func (x customSort) Swap(i, j int)      { x.p[i], x.p[j] = x.p[j], x.p[i] }

让我们定义一个根据多字段排序的函数,它主要的排序键是Age,Age 相同了再按 Name 进行倒序排序。下面是该排序的调用,其中这个排序使用了匿名排序函数:

sort.Sort(customSort{persons, func(x, y *Person) bool {if x.Age != y.Age {return x.Age < y.Age}if x.Name != y.Name {return x.Name > y.Name}return false
}})

排序具体的算法和复杂度

Go 的sort包中所有的排序算法在最坏的情况下会做 n log n次 比较,n 是被排序序列的长度,所以排序的时间复杂度是 O(n log n*)。其大多数的函数都是用改良后的快速排序算法实现的。

Go中的三种排序方法相关推荐

  1. Oracle的join默认为,Oracle中的三种Join方法详解

    这里将为大家介绍Oracle中的三种Join方法,Nested loop join.Sort merge join和Hash join.整理出来以便帮助大家学习. 基本概念 Nested loop j ...

  2. oracle hash join outer,CSS_浅谈Oracle中的三种Join方法,基本概念 Nested loop join: Outer - phpStudy...

    浅谈Oracle中的三种Join方法 基本概念 Nested loop join: Outer table中的每一行与inner table中的相应记录join,类似一个嵌套的循环. Sort mer ...

  3. 二叉树的三种排序方法

    二叉树的三种排序方法 1.前序排列 :根-左子-右子 1->2->4->5->8->10->9->3->6->7 2.中序排列:左子-根-右子 4 ...

  4. java中的五种排序方法_用Java排序的五种有用方法

    java中的五种排序方法 Java排序快速概述: 正常的列表: private static List VEGETABLES = Arrays.asList("apple", &q ...

  5. catia如何整列加工_CATIA装配模块中的三种阵列方法

    CATIA装配模块中有三种零件阵列方法: 1. 定义多实例化 2. 快速多实例化 3. 重复使用阵列 其中"重复使用阵列"方式是实际工作中使用最多的一种,本次将重点介绍该方式的使用 ...

  6. 一文介绍机器学习中的三种特征选择方法

    作者 | luanhz 来源 | 小数志 导读 机器学习中的一个经典理论是:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限.也正因如此,特征工程在机器学习流程中占有着重要地位.广义的特征 ...

  7. 软件测试三种错误的是,软件测试中的三种排错方法(知识篇)

    1.排错过程 测试用例的执行是排错过程的开始,若测试结果与期望结果有出入,即出现了错误征兆,排错过程首先要找出错误原因,然后对错误进行修正.因此排错过程有两种可能,一是找到了错误原因并纠正了错误,另一 ...

  8. PHP中数组的三种排序方法

    一.冒泡排序法 说明:找到最大的数,排列到最后面,然后继续找 例: $arr = array(3,5,-1,0,2); for($i=0;$i<count($arr)-1;$i++){ for( ...

  9. 一维数组简介及三种排序方法

    数组简介: 数组是用来存储数据的集合,但是,通常我们会把数组看作一个存储具有相同类型 的变量集合会更有用.无须声明单个变量,例如:number0, number1,-,number99, 只要声明一个 ...

最新文章

  1. Strusts2 高危漏洞又来了,老项目自查起来!
  2. A single input file is required for a non-link phase when an outputfile is specified
  3. IDEA搭建Maven Web(SSM)项目(一)——创建项目
  4. 2016c语言模拟试卷一,2016年9月计算机二级C语言考试预测试题及答案(4)
  5. Latex Smartdiagram
  6. sql对查询的一列结果进行去重
  7. powerbi实时刷新mysql数据库_PowerBI开发 第七篇:数据集和数据刷新
  8. 切换Debug/Release编译模式和Archive的作用
  9. 第5章 Python 数字图像处理(DIP) - 图像复原与重建3 - 爱尔兰(伽马)噪声
  10. 优酷视频如何修改账号密码?
  11. ADO.NET与Sql Server和Access的连接
  12. Spring Boot 操作 Memcache
  13. 【Jenkins】Jenkins配置从节点,实现远程主机调用功能
  14. 计算机毕业设计中用python神经网络编程实现手写数字识别
  15. ZooKeeper 基本操作
  16. ACE_Reactor学习1 总体计划
  17. 删除字符串中指定位置的字符
  18. fckeditor php 不显示,PHP Fckeditor上传文件(或图片)中文显示为乱码的解决方法
  19. Container 系列 - NAS - Introduction
  20. DBUtils详细介绍+实例

热门文章

  1. 使用git将code同时提交github,gitee,coding
  2. 极光推送---安卓Demo
  3. VMWare虚拟系统上网设置及VMWare虚拟机三种工作模式详解
  4. c#遍历一个文件夹下的所有文件包括子文件夹【原】
  5. Mysql批量更新的一个坑-allowMultiQueries=true允许批量更新
  6. jquery工具方法parseJSON
  7. Solr6.1 smartCN配置
  8. MySQL索引类型总结和使用技巧以及注意事项
  9. Git学习(4)基本操作
  10. python下保持mysql连接,避免“MySQL server has gone away“方法