Golang中如何理解反向排序
Golang中如何理解反向排序 这里可能有些非常简单的东西我没理解,但我实在想不通反向排序的工作原理。
https://golang.org/pkg/sort/#example_Reverse
要对切片进行排序,我这样做:
sort.Sort(myslice)
但要反向排序,我必须这样做:
sort.Sort(sort.Reverse(myslice))
根据文档说明,“Reverse返回数据的逆序”,那么sort.Reverse不应该是按逆序排序,然后sort.Sort再把切片恢复成正常顺序吗?然而如果我只执行sort.Reverse,似乎什么变化都没有发生。
更多关于Golang中如何理解反向排序的实战教程也可以访问 https://www.itying.com/category-94-b0.html
好的,我明白了。这虽然有点让我脑筋转不过弯,但我理解了。
谢谢。
更多关于Golang中如何理解反向排序的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我确实注意到了提到接口而不是切片,但当时没有真正理解。这个描述很好且很有道理,我会构建几个示例来实际观察它的运行效果。谢谢。
你在耍小聪明 😉
文档明确指出 sort.Sort 接收的是 sort.Interface 接口类型,而不是切片!
该接口需要实现三个方法:Len、Swap 和 Less。其中 Less 方法接收切片的两个元素作为参数,如果第一个元素应该排在第二个元素之前,则返回 true。
sort.Reverse 会接收 sort.Interface 并对其 Less 方法的结果取反,从而反转排序顺序。
这样解释清楚了吗?
除了使用 p.reverse(及相关代码),您确实可以使用 sort.Reverse。
此外,我建议针对 “sortByKey” 布尔值创建两种不同的排序接口实现。基本上,只需定义两种类型:
type pairSortValue []Pair
type pairSortKey []Pair
…并为两者都实现 Len()、Swap() 和 Less() 方法。
当您需要排序时:
sort.Sort(pairSortValue(ps))
sort.Sort(sort.Reverse(pairSortKey(ps)))
(其中 ps 是 Pair 的切片。)
我尝试了一下,看起来都能理解,这样实现按键或值对键/值结构进行排序,并且能够反转排序顺序,你觉得怎么样?
package main
import "fmt"
import "sort"
type Pair struct {
Key string
Value int
}
type PairList struct {
p []Pair
sortByKey bool
reverse bool
}
func (p PairList) Len() int { return len(p.p) }
func (p PairList) Swap(i, j int) { p.p[i], p.p[j] = p.p[j], p.p[i] }
func (p PairList) Less(i, j int) bool {
if p.sortByKey {
我已经重写了它,现在看起来好多了。
digininja/go_practice/blob/master/sort/main.go
package main
import "fmt"
import "sort"
type Pair struct {
Key string
Value int
}
type PairListValueSort []Pair
type PairListKeySort []Pair
type PairList []Pair
func (p PairListValueSort) Len() int { return len(p) }
func (p PairListValueSort) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p PairListValueSort) Less(i, j int) bool {
return p[i].Value < p[j].Value
}
此文件已被截断。显示完整内容
在Go语言中,sort.Reverse函数本身并不会执行排序操作,它只是返回一个包装了原始数据的新接口,该接口的Less方法被反转了。
让我用一个完整的例子来解释:
package main
import (
"fmt"
"sort"
)
func main() {
numbers := []int{3, 1, 4, 1, 5, 9, 2, 6}
fmt.Println("原始切片:", numbers)
// 正常排序(升序)
sort.Sort(sort.IntSlice(numbers))
fmt.Println("升序排序:", numbers)
// 重置数据
numbers = []int{3, 1, 4, 1, 5, 9, 2, 6}
// 反向排序(降序)
sort.Sort(sort.Reverse(sort.IntSlice(numbers)))
fmt.Println("降序排序:", numbers)
// 只调用 Reverse 不会改变数据
numbers = []int{3, 1, 4, 1, 5, 9, 2, 6}
reversed := sort.Reverse(sort.IntSlice(numbers))
fmt.Println("只调用 Reverse:", numbers)
// 需要调用 Sort 才会实际排序
sort.Sort(reversed)
fmt.Println("调用 Sort 后:", numbers)
}
输出结果:
原始切片: [3 1 4 1 5 9 2 6]
升序排序: [1 1 2 3 4 5 6 9]
降序排序: [9 6 5 4 3 2 1 1]
只调用 Reverse: [3 1 4 1 5 9 2 6]
调用 Sort 后: [9 6 5 4 3 2 1 1]
关键点在于:
sort.Reverse返回一个包装器,它反转了Less方法的逻辑- 原本的
Less(i, j int) bool返回true表示i应该在j前面 - 反转后的
Less(i, j int) bool返回true表示i应该在j后面 - 只有调用
sort.Sort时才会实际执行排序算法
对于自定义类型也是如此:
type Person struct {
Name string
Age int
}
type ByAge []Person
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func main() {
people := []Person{
{"Alice", 25},
{"Bob", 30},
{"Charlie", 20},
}
// 按年龄升序
sort.Sort(ByAge(people))
fmt.Println("按年龄升序:", people)
// 按年龄降序
sort.Sort(sort.Reverse(ByAge(people)))
fmt.Println("按年龄降序:", people)
}
sort.Reverse的作用就是改变排序的比较逻辑,而sort.Sort才是真正执行排序的算法。

