You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 03:40:38