该包实现了四种基本排序算法:插入排序、归并排序、堆排序和快速排序。 但是这四种排序方法是不公开的,它们只被用于sort包内部使用。所以在对数据集合排序时不必考虑应当选择哪一种排序方法,只要实现了sort.Interface定义的三个方法:获取数据集合长度的Len()方法、比较两个元素大小的Less()方法和交换两个元素位置的Swap()方法,就可以顺利对数据集合进行排序。sort包会根据实际数据自动选择高效的排序算法。 除此之外,为了方便对常用数据类型的操作,sort包提供了对[]int切片、[]float64切片和[]string切片完整支持,主要包括:

对基本数据类型切片的排序支持

基本数据元素查找

判断基本数据类型切片是否已经排好序

对排好序的数据集合逆序

3.1.1 数据集合排序

前面已经提到过,对数据集合(包括自定义数据类型的集合)排序需要实现sort.Interface接口的三个方法,我们看以下该接口的定义:

type Interface interface {

// 获取数据集合元素个数

Len() int

// 如果i索引的数据小于j所以的数据,返回true,不会调用

// 下面的Swap(),即数据升序排序。

Less(i, j int) bool

// 交换i和j索引的两个元素的位置

Swap(i, j int)

}

数据集合实现了这三个方法后,即可调用该包的Sort()方法进行排序。 Sort()方法定义如下:

`func Sort(data Interface)`

Sort()方法惟一的参数就是待排序的数据集合。

该包还提供了一个方法可以判断数据集合是否已经排好顺序,该方法的内部实现依赖于我们自己实现的Len()和Less()方法:

func IsSorted(data Interface) bool {

n := data.Len()

for i := n - 1; i > 0; i-- {

if data.Less(i, i-1) {

return false

}

}

return true

}

下面是一个使用sort包对学生成绩排序的示例:

package main

import (

"fmt"

"sort"

)

//学生成绩结构体

type StuScore struct {

//姓名

name string

//成绩

score int

}

type StuScores []StuScore

//Len()

func (s StuScores) Len() int {

return len(s)

}

//Less():成绩将有低到高排序

func (s StuScores) Less(i, j int) bool {

return s[i].score < s[j].score

}

//Swap()

func (s StuScores) Swap(i, j int) {

s[i], s[j] = s[j], s[i]

}

func main() {

stus := StuScores{

{"alan", 95},

{"hikerell", 91},

{"acmfly", 96},

{"leao", 90}}

fmt.Println("Default:")

//原始顺序

for _, v := range stus {

fmt.Println(v.name, ":", v.score)

}

fmt.Println()

//StuScores已经实现了sort.Interface接口

sort.Sort(stus)

fmt.Println("Sorted:")

//排好序后的结构

for _, v := range stus {

fmt.Println(v.name, ":", v.score)

}

//判断是否已经排好顺序,将会打印true

fmt.Println("IS Sorted?", sort.IsSorted(stus))

}

程序该示例程序的自定义类型StuScores实现了sort.Interface接口,所以可以将其对象作为sort.Sort()和sort.IsSorted()的参数传入。运行结果:

======Default======

alan : 95

hikerell : 91

acmfly : 96

leao : 90

======Sorted=======

leao : 90

hikerell : 91

alan : 95

acmfly : 96

IS Sorted? true

该示例实现的是升序排序,如果要得到降序排序结果,其实只要修改Less()函数:

//Less():成绩降序排序,只将小于号修改为大于号

func (s StuScores) Less(i, j int) bool {

return s[i].score > s[j].score

}

此外,sort包提供了Reverse()方法,可以允许将数据按Less()定义的排序方式逆序排序,而不必修改Less()代码。方法定义如下:

func Reverse(data Interface) Interface

我们可以看到Reverse()返回的一个sort.Interface接口类型,整个Reverse()的内部实现比较有趣:

//定义了一个reverse结构类型,嵌入Interface接口

type reverse struct {

Interface

}

//reverse结构类型的Less()方法拥有嵌入的Less()方法相反的行为

//Len()和Swap()方法则会保持嵌入类型的方法行为

func (r reverse) Less(i, j int) bool {

return r.Interface.Less(j, i)

}

//返回新的实现Interface接口的数据类型

func Reverse(data Interface) Interface {

return &reverse{data}

}

了解内部原理后,可以在学生成绩排序示例中使用Reverse()来实现成绩升序排序:

sort.Sort(sort.Reverse(stus))

for _, v := range stus {

fmt.Println(v.name, ":", v.score)

}

最后一个方法:Search()

func Search(n int, f func(int) bool) int

官方文档这样描述该方法:

Search()方法回使用“二分查找”算法来搜索某指定切片[0:n],并返回能够使f(i)=true的最 小的i(0<=i

i之前的切片元素会使f()函数返回false,i及i之后的元素会使f()函数返回true。但是,当 在切片中无法找到时f(i)=true的i时(此时切片元素都不能使f()函数返回true),Search() 方法会返回n。

Search()函数一个常用的使用方式是搜索元素x是否在已经升序排好的切片s中:

x := 11

s := []int{3, 6, 8, 11, 45} //注意已经升序排序

pos := sort.Search(len(s), func(i int) bool { return s[i] >= x })

if pos < len(s) && s[pos] == x {

fmt.Println(x, "在s中的位置为:", pos)

} else {

fmt.Println("s不包含元素", x)

}

官方文档还给出了一个猜数字的小程序:

func GuessingGame() {

var s string

fmt.Printf("Pick an integer from 0 to 100.\n")

answer := sort.Search(100, func(i int) bool {

fmt.Printf("Is your number <= %d? ", i)

fmt.Scanf("%s", &s)

return s != "" && s[0] == 'y'

})

fmt.Printf("Your number is %d.\n", answer)

}

3.1.2 sort包已经支持的内部数据类型排序

前面已经提到,sort包原生支持[]int、[]float64和[]string三种内建数据类型切片的排序操作,即不必我们自己实现相关的Len()、Less()和Swap()方法。

IntSlice类型及[]int排序

由于[]int切片排序内部实现及使用方法与[]float64和[]string类似,所以只详细描述该部分。

sort包定义了一个IntSlice类型,并且实现了sort.Interface接口:

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] }

//IntSlice类型定义了Sort()方法,包装了sort.Sort()函数

func (p IntSlice) Sort() { Sort(p) }

//IntSlice类型定义了SearchInts()方法,包装了SearchInts()函数

func (p IntSlice) Search(x int) int { return SearchInts(p, x) }

并且提供的sort.Ints()方法使用了该IntSlice类型:

`func Ints(a []int) { Sort(IntSlice(a)) }`

所以,对[]int切片排序是更常使用sort.Ints(),而不是直接使用IntSlice类型:

s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据

sort.Ints(s)

fmt.Println(s) //将会输出[1 2 3 4 5 6]

如果要使用降序排序,显然要用前面提到的Reverse()方法:

s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据

sort.Sort(sort.Reverse(sort.IntSlice(s)))

fmt.Println(s) //将会输出[6 5 4 3 2 1]

如果要查找整数x在切片a中的位置,相对于前面提到的Search()方法,sort包提供了SearchInts():

`func SearchInts(a []int, x int) int`

注意,SearchInts()的使用条件为:切片a已经升序排序

s := []int{5, 2, 6, 3, 1, 4} // 未排序的切片数据

sort.Ints(s) //排序后的s为[1 2 3 4 5 6]

fmt.Println(sort.SearchInts(s, 3)) //将会输出2

Float64Slice类型及[]float64排序

实现与Ints类似,只看一下其内部实现:

type Float64Slice []float64

func (p Float64Slice) Len() int { return len(p) }

func (p Float64Slice) Less(i, j int) bool { return p[i] < p[j] || isNaN(p[i]) && !isNaN(p[j]) }

func (p Float64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

func (p Float64Slice) Sort() { Sort(p) }

func (p Float64Slice) Search(x float64) int { return SearchFloat64s(p, x) }

与Sort()、IsSorted()、Search()相对应的三个方法:

func Float64s(a []float64)

func Float64sAreSorted(a []float64) bool

func SearchFloat64s(a []float64, x float64) int

要说明一下的是,在上面Float64Slice类型定义的Less方法中,有一个内部函数isNaN()。 isNaN()与math包中IsNaN()实现完全相同,sort包之所以不使用math.IsNaN(),完全是基于包依赖性的考虑,应当看到,sort包的实现不依赖与其他任何包。

StringSlice类型及[]string排序

两个string对象之间的大小比较是基于“字典序”的。

实现与Ints类似,只看一下其内部实现:

type StringSlice []string

func (p StringSlice) Len() int { return len(p) }

func (p StringSlice) Less(i, j int) bool { return p[i] < p[j] }

func (p StringSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }

func (p StringSlice) Sort() { Sort(p) }

func (p StringSlice) Search(x string) int { return SearchStrings(p, x) }

与Sort()、IsSorted()、Search()相对应的三个方法:

func Strings(a []string)

func StringsAreSorted(a []string) bool

func SearchStrings(a []string, x string) int

golang的int64排序_golang sort —— 排序算法相关推荐

  1. c语言sort函数从小到大排序指针,sort排序是从小到大

    java数组排序问题:array.sort()是从小到大排序,别告诉我从i=a.length开始打印然后i.因为数组没变啊,只是打印顺序变Integer [] array=new Integer[]{ ...

  2. linux sort命令 排序,Linux sort排序方法

    在文件的操作过程中,因为文件过多,往往需要进行一下排序,排序方法也就是从小到大排序或者从大到小排序.比如我们从nginx日志中需要找到访问量最长的url,那就需要对请求时间进行一个排序,根据请求时间长 ...

  3. 奇偶排序(OddEven Sort)----(排序算法十一)

    1.算法原理 2.代码实现 #include <stdio.h>//printArray打印出数组 void printArray(int a[],int size){ printf(&q ...

  4. 鸡尾酒排序Cocktail Sort(排序算法九)

    1.算法原理 2.代码实现 #include <stdio.h>//printArray打印出数组 void printArray(int a[],int size){ printf(&q ...

  5. python列表反向排序_Python 列表排序方法reverse、sort、sorted详解

    python语言中的列表排序方法有三个:reverse反转/倒序排序.sort正序排序.sorted可以获取排序后的列表.在更高级列表排序中,后两中方法还可以加入条件参数进行排序. reverse() ...

  6. 【c/c++编程-排序问题】成绩排序、整数奇偶排序、国名排序、日志排序、字符串排序

    目录 成绩排序 整数奇偶排序1.0 成绩排序2.0 国名排序 日志排序 整数奇偶排序2.0 字符串排序 解一 解二 字符串排序3 后缀子串排序 EXCEL排序 特殊排序 成绩排序3.0 大整数排序 成 ...

  7. Golang sort 排序

    1.前言 开发过程中,我们经常需要对元素进行排序,使用 Go 我们可以轻松实现. Go 内置 sort 包中提供了根据一些排序函数可对任何序列进行排序,并提供自定义排序规则的能力. sort 包实现了 ...

  8. 经典排序算法 - 鸽巢排序Pigeonhole sort

    经典排序算法 - 鸽巢排序Pigeonhole sort 原理类似桶排序,同样需要一个很大的鸽巢[桶排序里管这个叫桶,名字无所谓了] 鸽巢其实就是数组啦,数组的索引位置就表示值,该索引位置的值表示出现 ...

  9. C++Bitonic Sort双调排序/比并排序的实现算法(附完整源码)

    C++Bitonic Sort双调排序/比并排序的实现算法 C++Bitonic Sort双调排序/比并排序的实现算法完整源码(定义,实现,main函数测试) C++Bitonic Sort双调排序/ ...

最新文章

  1. 智能POS常见问题整理
  2. Flex 3 与 Flex 4 beta 之间的区别
  3. 【C++11新特性】 C++11智能指针之shared_ptr
  4. 使用Dockerfile部署vue项目
  5. 【修炼5】《基础篇》别把项目成功当目标
  6. 诚邀参加微软.NET俱乐部10月24日Windows 7社区发布会
  7. crontab 定时任务
  8. OpenCV模板匹配函数:matchTemplate()介绍
  9. LINUX doubango编译中prefix参数无效
  10. android 反编译去会员,反编译教程
  11. win10 系统无法远程桌面连接到服务器,Win10系统不能建立远程桌面连接总是连接不上如何解决...
  12. html中如何淡化背景图片,Word2010如何去除图片背景
  13. 第四次作业—四则运算
  14. 【数据结构与算法】之深入解析“情侣牵手”的求解思路与算法示例
  15. 会员管理有哪些功能呢?
  16. 租用稳定的网通服务器,网通租用服务器
  17. win7 计算机名称 ip6,Win7系统提示ipv6无网络访问权限的两种原因及解决方法
  18. llt自发光_“贝爷”联名款海系列新品得物独家首发,呼吁年轻人保护海洋环境...
  19. 共享电商即共享商圈的背后: 共创、共生、共享、共富,共赢的共富精神
  20. JS实现轮播图(手动切换+自动切换两种方法)

热门文章

  1. 定期备份微信聊天记录(职场必备)
  2. Struts spring ibatis的集成(连载一)---转
  3. 工程数学参考用书应用概率统计(陈魁)部分答案1~6章
  4. 【图像处理】OpenCV中的边缘检测
  5. centos7.4安装zabbix3.4
  6. windows系统给文件夹添加备注(详细版)
  7. Python: matplotlib.pyplot.imread函数介绍
  8. A股-进阶-股市中投资心理实战
  9. 班章管家讲解固收理财有危险吗?固收理财有什么危险?
  10. idea在整个项目里面搜索