Go 語言對於類型的要求非常嚴格,導致我們無法聲明一個 interface
類型的切片對其排序。所以這裡模仿 Go 的 sort 排序擴充包,實現對某個特定類型排序的方法。
查看完整代碼,點擊這裡
Interface 介面
若要實現一個自訂的排序,就要實現 sort 包的排序介面。要排序的集合必須包含一個數字類型的索引,所以待排序的資料類型只能是數組或者切片。
// A type, typically a collection, that satisfies sort.Interface can be// sorted by the routines in this package. The methods require that the// elements of the collection be enumerated by an integer index.type Interface interface { // Len is the number of elements in the collection. Len() int // Less reports whether the element with // index i should sort before the element with index j. Less(i, j int) bool // Swap swaps the elements with indexes i and j. Swap(i, j int)}
自訂排序的結構體
我們將對所有的學生進行排序,學生包含他的姓名以及成績,排序的規則是按照學習的成績排序。
type Student struct { Name string Score int}type Students []Student
實現排序的介面
func (s Students) Len() int { return len(s)}// 在比較的方法中,定義排序的規則func (s Students) Less(i, j int) bool { if s[i].Score < s[j].Score { return true } else if s[i].Score > s[j].Score { return false } else { return s[i].Name < s[i].Name }}func (s Students) Swap(i, j int) { temp := s[i] s[i] = s[j] s[j] = temp}
實現排序邏輯
Go 提供了基於快排實現的排序方法,這裡為了體驗為什麼 Go 這麼定義 Interface 介面,我使用了選擇排序的方法代替 Go 的快排。
func Sort(s sort.Interface) { length := s.Len() for i := 0; i < length; i++ { minIndex := i for j := i + 1; j < length; j++ { if s.Less(j, i) { minIndex = j } } s.Swap(minIndex, i) }}
在這個排序中,我使用了介面中定義的三個方法: Len()
,Less()
,Swap()
。最重要的還是 Less()
,沒有它程式就不知道如何去比較兩個未知元素的大小。
重寫輸出
為了更好的輸出學生的資訊,重寫學生的字串輸出格式
func (s Student) String() string { return fmt.Sprintf("Student: %s %v", s.Name, s.Score)}
測試輸出
通過以下程式測試我們的排序演算法
func main() { arr := []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1} SelectionSort(arr, len(arr)) fmt.Println(arr) students := student.Students{} students = append(students, student.Student{"D", 90}) students = append(students, student.Student{"C", 100}) students = append(students, student.Student{"B", 95}) students = append(students, student.Student{"A", 95}) Sort(students) for _, student := range students { fmt.Println(student) }}
以下是輸出結果:
[1 2 3 4 5 6 7 8 9 10]Student: D 90Student: A 95Student: B 95Student: C 100