Rust中为结构体实现两种排序规则的二叉堆(优先队列)
Rust实现基于不同属性排序的二叉堆(优先队列)
Rust标准库中的BinaryHeap是最大堆,默认要求元素实现Ord trait来确定优先级。要为同一个Dog结构体实现两种不同的排序逻辑(按age升序、按weight升序),我们需要通过包装结构体来分别实现不同的Ord规则——因为单个结构体无法同时拥有多套Ord实现。
步骤1:定义包装结构体
为每种排序规则创建一个包装类型,内部持有Dog实例:
#[derive(Debug, Clone, Eq, PartialEq)] struct AgeOrderedDog(Dog); // 按age升序排序的包装 #[derive(Debug, Clone, Eq, PartialEq)] struct WeightOrderedDog(Dog); // 按weight升序排序的包装
步骤2:为包装结构体实现排序逻辑
因为BinaryHeap是最大堆,要实现最小元素优先弹出(符合你的需求:age小的先出、weight小的先出),我们需要反转属性的比较结果,让更小的元素被堆判定为“优先级更高”的元素。
按age排序的实现
impl Ord for AgeOrderedDog { fn cmp(&self, other: &Self) -> std::cmp::Ordering { // 反转age的比较:other的age比self小 → 返回Greater,让小age的元素优先弹出 other.0.age.cmp(&self.0.age) } } impl PartialOrd for AgeOrderedDog { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(other)) } }
按weight排序的实现
impl Ord for WeightOrderedDog { fn cmp(&self, other: &Self) -> std::cmp::Ordering { // 反转weight的比较:other的weight比self小 → 返回Greater,让小weight的元素优先弹出 other.0.weight.cmp(&self.0.weight) } } impl PartialOrd for WeightOrderedDog { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(other)) } }
步骤3:使用自定义优先队列
将Dog实例包装后放入BinaryHeap,即可得到符合预期的弹出顺序:
fn main() { let d1 = Dog::new(1, 3); let d2 = Dog::new(2, 2); let d3 = Dog::new(3, 1); // 按age排序的堆:弹出顺序d1 → d2 → d3 let mut age_heap = std::collections::BinaryHeap::new(); age_heap.push(AgeOrderedDog(d1.clone())); age_heap.push(AgeOrderedDog(d2.clone())); age_heap.push(AgeOrderedDog(d3.clone())); while let Some(AgeOrderedDog(dog)) = age_heap.pop() { println!("Age: {}, Weight: {}", dog.age, dog.weight); } println!("---"); // 按weight排序的堆:弹出顺序d3 → d2 → d1 let mut weight_heap = std::collections::BinaryHeap::new(); weight_heap.push(WeightOrderedDog(d1)); weight_heap.push(WeightOrderedDog(d2)); weight_heap.push(WeightOrderedDog(d3)); while let Some(WeightOrderedDog(dog)) = weight_heap.pop() { println!("Age: {}, Weight: {}", dog.age, dog.weight); } }
补充说明
如果需要最大元素优先弹出,只需去掉比较逻辑的反转即可。比如要让age大的先出,AgeOrderedDog的cmp方法直接写self.0.age.cmp(&other.0.age)即可。
内容的提问来源于stack exchange,提问作者redrobinyum
相关产品推荐
相关产品推荐

