golang标准库-排序(sort)

sort包,顾名思义用来排序的包,里面提供的工具方法可以对int,string,float64类型的切片进行快速排序和查找,如果自己定义的数据类型,实现了sort.Interface类型接口,也可以进行排序和查找。这个包方法不算多,也不复杂。本文讲解了sort包90%的内容

先看三个类型的基本排序方法:

func Ints(a []int) // 将a排序为递增顺序。
func Float64s(a []float64) // 将a排序为递增顺序。
func Strings(a []string) // 将a排序为递增顺序。

下面看例子,分别对int,float64,string类型的切片进行排序:

func main() {
	// 对int切片快速排序
	i := []int{3,2,1,12,32,5,3}
	sort.Ints(i)
	fmt.Println(i) // 结果:[1 2 3 3 5 12 32]

	// 对float64切片快速排序
	f := []float64{0.6,9.4,0.4,1.2,3.1}
	sort.Float64s(f)
	fmt.Println(f) // 结果:[0.4 0.6 1.2 3.1 9.4]

	// 对string切片快速排序
	s := []string{"a","A","AA","aa","Aa","aA","AAA","AAa","b","bA","abA"} // string类型比较特殊,这里我们的数据也设置的比较特殊,看sort包对它们是怎么排序的
	sort.Strings(s)
	fmt.Println(s) // 结果:[A AA AAA AAa Aa a aA aa abA b bA],可以看到,对string类型排序,比较的是字符的ASCII表
}

输出的结果这里不再用图片展示,文中有注释,节省篇幅,结果肯定是对的。

其实看到这里,足以应对我们日常开发对数据排序的需求,下面我们继续深入认识sort包的包装类型:

sort包提供了三个基本的包装类型:

type IntSlice []int
type StringSlice []string
type Float64Slice []float64

可以看到,上面的三个类型都是对int,string,float64切片的封装,这个三个类型都实现了sort包的Interface接口,下面我们来看Interface接口:

type Interface interface {
    // Len方法返回集合中的元素个数
    Len() int
    // Less方法判断索引i的元素值是否比索引j的元素值小
    Less(i, j int) bool
    // Swap方法交换索引i和j的两个值
    Swap(i, j int)
}

下面以 IntSlice 类型举例演示,StringSlice和Float64Slice类型都一样,都有同样的方法,就不再重复演示了。

IntSlice类型除了实现Interface接口的三个方法外,还有自己的其它方法,我们主要用到的也是它自己的方法:

func (p IntSlice) Sort() // 对p进行排序
func (p IntSlice) Search(x int) int // 搜索p中是否含有x值,有的话,返回p中的索引,没有就放回元素x在p中应该存在的位置
// StringSlice和Float64Slice 也实现了这两个方法
func main() {

	var s sort.IntSlice = []int{1,4,2,6,4,3} // 声明一个IntSlice变量

	fmt.Println(s.Len()) // 打印长度 6
	fmt.Println(sort.IsSorted(s)) // sort方法:判断切片类型的数据是不是有序的, 这里打印false
	s.Sort() // 进行排序
	fmt.Println(sort.IsSorted(s)) // 打印true,上一步已经排好序了
	fmt.Println(s) // 打印 [1 2 3 4 4 6]

	// 搜索切片中的值,插一句,go在这里的搜索方法底层用的二分查找法,感兴趣的读者可以去看源码
	fmt.Println(s.Search(4)) // 打印 3
	fmt.Println(s.Search(2)) // 打印 1
	fmt.Println(s.Search(5)) // 打印 5, s中没有5,但按顺序,5应该在4和6之间,所有返回索引5

}

到这里sort包就介绍完了。下面我们再深入,自己声明一个数据类型,并且实现Interface接口,用sort包的方法进行排序:

1.声明数据类型

// 声明一个person类型结构体
type person struct {
   id int
   name string
}

// 声明一个person切片类型别名
type ps []person

2.实现Interface接口

func (p ps) Len() int { // 实现len方法
   return len(p)
}

func (p ps) Swap(i,j int) { // 实现Swap方法,交换i,j的位置
   p[i], p[j] = p[j], p[i]
}

// 实现Less方法,排序方法(Sort)主要就是根据这个方法来进行数据大小的比较,我们根据p的id大小比较
func (p ps) Less(i,j int) bool { 
   return p[i].id < p[j].id
}

3.现在可以对person结构体切片进行排序了,下面看代码:

func main() {

	// 声明一个ps类型数据
	var s ps = []person{{1,"go"},{7,"java"},{3,"js"},{2,"c"}}
	fmt.Println(sort.IsSorted(s)) // 打印 false
	// 对它进行排序
	sort.Sort(s)
	fmt.Println(sort.IsSorted(s)) // 打印 true
	fmt.Println(s) // 打印 [{1 go} {2 c} {3 js} {7 java}]
}

致此,sort包算是讲完了。

你可能感兴趣的:(go,golang标准库)