Chuyển đến nội dung chính
Mô-đun 4 · Bài học 5 trong tổng số 520/50 trong khóa học~10 min
Bài học theo mô-đun (5/5)

Sắp xếp với gói sắp xếp

Gói sort tiêu chuẩn sắp xếp các lát tại chỗ. Đối với các loại cơ sở (int, float64, string) có người trợ giúp trực tiếp; cho bất kỳ phần nào khác mà bạn sử dụng sort.Slice với hàm less(i, j int) bool xác định đặt hàng.

Trợ giúp cho các loại cơ sở

Go
import "sort"

nums := []int{5, 2, 8, 1}
sort.Ints(nums)        // [1 2 5 8]

words := []string{"c", "a", "b"}
sort.Strings(words)    // [a b c]

fs := []float64{1.5, 0.5, 2.5}
sort.Float64s(fs)      // [0.5 1.5 2.5]

Việc sắp xếp tại chỗ: lát cắt ban đầu bị đột biến.

sort.Slice: sắp xếp tùy chỉnh

Bạn chuyển lát cắt và hàm less, cho hai chỉ số i và j, trả về true nếu phần tử i phải đến trước j:

Go
type Person struct {
    Name string
    Age  int
}

people := []Person{
    {"Bruno", 30},
    {"Anna", 25},
    {"Carla", 28},
}

sort.Slice(people, func(i, j int) bool {
    return people[i].Age < people[j].Age
})
// Anna(25), Carla(28), Bruno(30)

Để sắp xếp ngược lại, chỉ cần lật so sánh: return people[i].Age > people[j].Age.

Sắp xếp ổn định

sort.Slice không được đảm bảo ổn định (các phần tử "bằng" có thể thay đổi thứ tự tương đối). Để sắp xếp ổn định, hãy sử dụng sort.SliceStable:

Go
sort.SliceStable(people, func(i, j int) bool {
    return people[i].Age < people[j].Age
})

Sắp xếp theo nhiều phím

Mẫu chung: sắp xếp theo độ tuổi và độ tuổi bằng nhau theo tên:

Go
sort.Slice(people, func(i, j int) bool {
    if people[i].Age != people[j].Age {
        return people[i].Age < people[j].Age
    }
    return people[i].Name < people[j].Name
})

Tìm kiếm nhị phân

sort.SearchInts / sort.Search hoạt động trên các lát đã được sắp xếp sẵn:

Go
nums := []int{1, 3, 5, 7, 9}
i := sort.SearchInts(nums, 5)   // 2

Nếu phần tử không có ở đó, nó sẽ trả về chỉ mục chèn. Bạn có thể đào vào các chi tiết khi bạn cần chúng.

Thuốc gốc (Đi 1.21+): slices.Sort

Từ gói slices trong stdlib (Go 1.21):

Go
import "slices"

nums := []int{3, 1, 2}
slices.Sort(nums)               // [1 2 3]
slices.SortFunc(people, func(a, b Person) int {
    return a.Age - b.Age        // -1/0/1
})

API hiện đại hơn, an toàn hơn. Tương thích với sort.Slice nhưng hơn thế nữa công thái học.

Hãy thử nó

tập thể dục#go.m4.l5.e1
Nỗ lực: 0Đang tải…

Sắp xếp các số theo thứ tự tăng dần bằng cách sử dụng Sort.Ints.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

`sort.Ints` sắp xếp một lát int tại chỗ.

Giải pháp khả dụng sau 3 lần thử

tập thể dục#go.m4.l5.e2
Nỗ lực: 0Đang tải…

Sắp xếp mọi người theo Độ tuổi theo thứ tự tăng dần bằng cách sử dụng Sort.Slice.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

Hàm less trả về true khi phần tử i xuất hiện TRƯỚC j.

Giải pháp khả dụng sau 3 lần thử

Quiz#go.m4.l5.e3
Sẵn sàng

Làm cách nào để sắp xếp theo thứ tự giảm dần với Sort.Slice?

Go
sort.Slice(s, func(i, j int) bool { return ??? })
Tùy chọn trả lời

Tóm tắt lại

  • sort.Ints / sort.Strings / sort.Float64s dành cho các loại cơ sở, tại chỗ.
  • sort.Slice(s, less) cho các lát thuộc bất kỳ loại nào, có chức năng less(i, j).
  • sort.SliceStable để duy trì thứ tự tương đối cho các khóa bằng nhau.
  • Sắp xếp theo nhiều khóa: một tầng if bên trong less.
  • Lên phiên bản 1.21+: gói slices có API chung (slices.Sort, slices.SortFunc).
  • Đối với key bản đồ: trích thành từng lát và sắp xếp.