sort summary
好的,这里为您总结了 C++、Java、Python、Golang 和 Rust 这些主流语言的排序方法,特别是自定义排序的实现方式。
概述
语言 | 内置排序方法 | 主要特点 | 自定义排序核心 |
---|---|---|---|
C++ | std::sort | 非常高效,通常是 IntroSort | 函数对象 (Functor)、Lambda、普通函数 |
Java | Arrays.sort() , Collections.sort() | 对象使用 TimSort,基础类型使用快速排序 | Comparator 接口(Lambda 或匿名类) |
Python | sorted() , list.sort() | 稳定,使用 TimSort | key 函数 或 cmp 函数(老式,不推荐) |
Golang | sort.Sort() , sort.Slice() | 使用快速排序 | 实现 sort.Interface 或使用 sort.Slice 与 Less 函数 |
Rust | slice.sort() , vec.sort() | 稳定,使用归并排序(TimSort 变种) | 闭包 (Closure) 传递给 sort_by 或实现 Ord /PartialOrd |
1. C++
C++ 主要使用 <algorithm>
库中的 std::sort
函数,它非常高效。
a) 对基本容器(如 vector<int>
)排序
#include <algorithm>
#include <vector>
std::vector<int> vec = {4, 2, 5, 3, 1};
// 默认升序
std::sort(vec.begin(), vec.end());
// 降序
std::sort(vec.begin(), vec.end(), std::greater<int>());
b) 自定义排序(Lambda - 最常用)
struct Person {
std::string name;
int age;
};
std::vector<Person> people = {{"Alice", 25}, {"Bob", 20}, {"Charlie", 23}};
// 按 age 升序排序
std::sort(people.begin(), people.end(), [](const Person& a, const Person& b) {
return a.age < b.age;
});
// 按 name 字典序降序排序
std::sort(people.begin(), people.end(), [](const Person& a, const Person& b) {
return a.name > b.name;
});
c) 自定义排序(函数对象 - Functor)
struct CompareByAge {
bool operator()(const Person& a, const Person& b) const {
return a.age < b.age;
}
};
std::sort(people.begin(), people.end(), CompareByAge());
2. Java
Java 对数组使用 Arrays.sort()
,对集合使用 Collections.sort()
。自定义排序通过 Comparator
接口实现。
a) 对数组和列表排序
import java.util.Arrays;
import java.util.Collections;
import java.util.ArrayList;
import java.util.Comparator;
int[] arr = {4, 2, 5, 3, 1};
Arrays.sort(arr); // 升序
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(4, 2, 5, 3, 1));
Collections.sort(list); // 升序
b) 自定义排序(Lambda - Java 8+)
class Person {
String name;
int age;
// ... 构造方法和 getter
}
ArrayList<Person> people = new ArrayList<>();
// ... 添加元素
// 按 age 升序
people.sort((a, b) -> a.age - b.age);
// 或
Collections.sort(people, (a, b) -> a.age - b.age);
// 按 name 字典序比较(使用 Comparator 工具方法)
people.sort(Comparator.comparing(Person::getName));
// 降序
people.sort(Comparator.comparing(Person::getName).reversed());
c) 自定义排序(匿名类 - 传统方式)
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person a, Person b) {
return a.age - b.age; // 升序
}
});
3. Python
Python 使用内置的 sorted()
函数(返回新列表)或列表的 sort()
方法(原地修改)。推荐使用 key
参数进行自定义排序。
a) 基本排序
my_list = [4, 2, 5, 3, 1]
# 升序
sorted_list = sorted(my_list)
my_list.sort()
# 降序
sorted_list = sorted(my_list, reverse=True)
my_list.sort(reverse=True)
b) 自定义排序(使用 key
参数 - 推荐)
key
函数将一个元素映射为一个用于比较的键。
people = [
{'name': 'Alice', 'age': 25},
{'name': 'Bob', 'age': 20},
{'name': 'Charlie', 'age': 23}
]
# 按 age 升序
sorted_people = sorted(people, key=lambda x: x['age'])
# 按 name 字典序降序
sorted_people = sorted(people, key=lambda x: x['name'], reverse=True)
c) 自定义排序(使用 cmp
参数 - 老旧方式,Python 3 中需 functools.cmp_to_key
)
如果需要更复杂的比较逻辑(例如先按年龄比,再按姓名比),可以使用老式的比较函数。
from functools import cmp_to_key
def compare(a, b):
# 先按年龄升序,年龄相同按姓名降序
if a['age'] != b['age']:
return a['age'] - b['age']
else:
return -1 if a['name'] > b['name'] else 1
sorted_people = sorted(people, key=cmp_to_key(compare))
4. Golang
Go 的排序在 sort
包中。自定义排序有两种主流方式:1) 实现 sort.Interface
;2) 使用 sort.Slice
(更简单)。
a) 基本类型排序
import "sort"
ints := []int{4, 2, 5, 3, 1}
sort.Ints(ints) // 升序
strs := []string{"Charlie", "Alice", "Bob"}
sort.Strings(strs) // 字典序升序
b) 自定义排序(实现 sort.Interface
)
需要为自定义类型实现 Len()
, Less(i, j int) bool
, Swap(i, j int)
三个方法。
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", 20}, {"Charlie", 23}}
sort.Sort(ByAge(people)) // 按 Age 升序排序
}
c) 自定义排序(使用 sort.Slice
- 更简单常用)
只需提供一个 Less
函数即可。
people := []Person{{"Alice", 25}, {"Bob", 20}, {"Charlie", 23}}
// 按 Age 升序
sort.Slice(people, func(i, j int) bool {
return people[i].Age < people[j].Age
})
// 按 Name 字典序降序
sort.Slice(people, func(i, j int) bool {
return people[i].Name > people[j].Name
})
5. Rust
Rust 中,可变切片(&mut [T]
)和向量(Vec<T>
)有 sort
方法。对于自定义排序,通常使用 sort_by
并传入一个闭包(Closure)。
a) 基本排序
let mut vec = vec![4, 2, 5, 3, 1];
vec.sort(); // 升序 (要求 T 实现 Ord Trait)
vec.sort_unstable(); // 更快的不稳定排序(对基础类型很好)
b) 自定义排序(使用 sort_by
和闭包)
#[derive(Debug)]
struct Person {
name: String,
age: u32,
}
fn main() {
let mut people = vec![
Person { name: "Alice".to_string(), age: 25 },
Person { name: "Bob".to_string(), age: 20 },
Person { name: "Charlie".to_string(), age: 23 },
];
// 按 age 升序排序
people.sort_by(|a, b| a.age.cmp(&b.age));
// 按 name 字典序降序排序
people.sort_by(|a, b| b.name.cmp(&a.name));
// 使用 then_by 进行链式比较(先按年龄,再按姓名)
people.sort_by(|a, b| a.age.cmp(&b.age).then_with(|| a.name.cmp(&b.name)));
}
c) 为自定义类型实现 Ord
/PartialOrd
Trait
如果希望你的类型可以直接使用 sort()
方法,需要为其实现 Ord
和 PartialOrd
Trait。
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
struct Person {
age: u32,
name: String,
}
// 这样实现后,Person 会先按 age 比较,再按 name 比较(字典序)
// 然后就可以直接调用 people.sort(); 了
总结与建议
- C++: Lambda 是自定义
std::sort
时最现代和简洁的方式。 - Java: Lambda 和
Comparator.comparing
是 Java 8 之后的首选,非常表达意图。 - Python:
key
函数是绝对的主流,简单高效。仅在复杂比较逻辑时才考虑cmp_to_key
。 - Golang:
sort.Slice
是大多数情况下的最佳选择,避免了实现整个接口的繁琐。 - Rust: 闭包与
sort_by
是最灵活和常用的组合。为类型实现Ord
则使其拥有默认的排序行为。