先考虑某一个具体类型的数组(比如[]int)的排序方式,实现如伪代码所示:
func sort(arr []int) {
for i := 0; i < len(arr)-1; i++ {
for j := i + 1; j < len(arr); j++ {
if arr[i] > arr[j] {
arr[i], arr[j] = arr[j], arr[i]
}
}
}
}
现仔细考察之,通过伪代码所示,我们如果对一个数组排序,需要知道:
- 数组的长度
- 数据里面任意两个元素的大小
- 交换数组里面的任意两个元素的位置
推广到一般情况,通用类型也应该具有这三种能力。另外,对于sort函数的签名,参数类型为[]int,为了能够传递通用类型的数组,也需要进化下。
以上两点,结合golang语言的特点,可以把通用类型数组type成一个interface,然后三个能力用方法来规定。接口定义可以设计成如下的样子:
type SortInterface interface {
Len() int
Cmp(i, j int) bool
Swap(i, j int)
}
- Len方法返回数组的元素个数
- Cmp方法返回两个下标对应的元素的大小
- Swap方法交换两个下标对应的元素位置
sort函数定义:
func sort(arr SortInterface) {
for i := 0; i < arr.Len()-1; i++ {
for j := i + 1; j < arr.Len(); j++ {
if arr.Cmp(i, j) {
arr.Swap(i, j)
}
}
}
}
由于我们定义了一个接口,并且接口定义了三个方法,只要是实现了了该接口的数组都可以对之排序。
举个例子:
如代码块所示,我们要对该数组排序:
arr := []int{1, 5, 2, 4, 7, 0, 9, 3, 5}
第一步,先type一个类型,比如:
type Array []int
第二步,实现接口三个方法
func (a Array) Cmp(i, j int) bool {
return a[i] - a[j] > 0
}
func (a Array) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func (a Array) Len() int {
return len(a)
}
加上测试代码,完整代码如下:
package main
import (
"fmt"
)
type Array []int
func (a Array) Cmp(i, j int) bool {
return a[i]-a[j] > 0
}
func (a Array) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}
func (a Array) Len() int {
return len(a)
}
type SortInterface interface {
Len() int
Cmp(i, j int) bool
Swap(i, j int)
}
func Sort(arr SortInterface) {
for i := 0; i < arr.Len()-1; i++ {
for j := i + 1; j < arr.Len(); j++ {
if arr.Cmp(i, j) {
arr.Swap(i, j)
}
}
}
}
func main() {
arr := []int{1, 5, 2, 4, 7, 0, 9, 3, 5}
fmt.Println(arr)
Sort(Array(arr))
fmt.Println(arr)
}
运行结果
╰─➤ go run main.go
[1 5 2 4 7 0 9 3 5]
[0 1 2 3 4 5 5 7 9]