rust - 如何创建自定义排序?
问题描述
我想使用标准库二进制堆形成以下数据结构: use std::collections::BinaryHeap;
let mut heap: BinaryHeap<BinaryHeap<(i32, usize, usize)>> = BinaryHeap::new();
并且总体 BinaryHeap 的顺序取决于包含的二进制堆中 peek 的最高值。例如,如果我在总体二进制堆中有两个堆,例如:
堆1:(3、0、5)、(2、0、6)堆2:(5、2、6)、(3、3、9)
然后我希望 heap2 成为总体堆中的最大项,因为它的 peek 值,即 (5, 2, 6) 大于 heap1 的 peek 值 (3, 0, 5)。我尝试了以下方法:
use std::collections::BinaryHeap;
use core::cmp::Ordering;
#[derive(Eq)]
struct MyBinaryHeap<T>(BinaryHeap<T>);
impl Ord for MyBinaryHeap<(i32, usize, usize)> {
fn cmp(&self, other: &Self) -> Ordering {
&self.peek().cmp(&other.peek());
}
}
impl PartialOrd for MyBinaryHeap<(i32, usize, usize)> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl PartialEq for MyBinaryHeap<(i32, usize, usize)> {
fn eq(&self, other: &Self) -> bool {
self.peek().0 == other.peek().0
}
}
但这给了我错误:
Line 3, Char 10: can't compare `MyBinaryHeap<T>` with `MyBinaryHeap<T>` (solution.rs)
|
3 | #[derive(Eq)]
| ^^ no implementation for `MyBinaryHeap<T> == MyBinaryHeap<T>`
|
= help: the trait `std::cmp::PartialEq` is not implemented for `MyBinaryHeap<T>`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
如何正确实现 Ord?此外,我还希望在某个内部堆中弹出一个元素时,这个总体堆能够工作。因此,如果其中的元素发生变化,堆应该能够自我调整。然而,自我调整的属性并不是硬性要求,没有它我也能活下去。
解决方案
-
如何正确实现 Ord?
Ord
要求类型也是PartialOrd
andEq
(需要PartialEq
)。因此(操场):
use std::collections::BinaryHeap; use core::cmp::Ordering; struct MyBinaryHeap<T>(BinaryHeap<T>); impl Ord for MyBinaryHeap<(i32, usize, usize)> { fn cmp(&self, other: &Self) -> Ordering { self.0.peek().cmp(&other.0.peek()) } } impl PartialOrd for MyBinaryHeap<(i32, usize, usize)> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } } impl PartialEq for MyBinaryHeap<(i32, usize, usize)> { fn eq(&self, other: &Self) -> bool { self.cmp(other) == Ordering::Equal } } impl Eq for MyBinaryHeap<(i32, usize, usize)> {}
但实际上,您可以更通用并将其应用于任何
T
(游乐场):use std::collections::BinaryHeap; use core::cmp::Ordering; struct MyBinaryHeap<T>(BinaryHeap<T>); impl<T: Ord> Ord for MyBinaryHeap<T> { fn cmp(&self, other: &Self) -> Ordering { self.0.peek().cmp(&other.0.peek()) } } impl<T: PartialOrd> PartialOrd for MyBinaryHeap<T> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { self.0.peek().partial_cmp(&other.0.peek()) } } impl<T: PartialEq> PartialEq for MyBinaryHeap<T> { fn eq(&self, other: &Self) -> bool { self.0.peek() == other.0.peek() } } impl<T: Eq> Eq for MyBinaryHeap<T> {}
-
当一个元素在一个内部堆中弹出时,我还希望这个总体堆能够工作。因此,如果其中的元素发生变化,堆应该能够自我调整。
如果只通过外部堆的
peek_mut()
方法修改内部堆,那么这是有保证的。
推荐阅读
- character - 在 gnuplot 中更改字符点类型的颜色
- java - jlink 图像中的语言环境 getDisplayLanguage 损坏
- android - 将用户数据从登录页面发送到主要活动并从主要活动中注销
- c# - Xaml 文件看不到命名空间中的类
- windows - WINDOWS Git-bash 运行 docker.sock
- firebase - 对使用自定义子域设置 Firebase 动态链接所需的 A 记录的担忧
- python-3.x - 如何将此类数据写入csv
- java - ScriptEngineManager 格外谨慎的异常处理
- angular - 如何在 Angular 项目中实现 google 身份验证?
- python - 如何使用 python 日志模块打印当前行