代码之家  ›  专栏  ›  技术社区  ›  Nevermore

如何创建弹出最小值而不是最大值的二进制堆?

  •  4
  • Nevermore  · 技术社区  · 5 年前

    std::collections::BinaryHeap 最小的 订购 pop ,但我的目标是从最小到最大遍历集合。

    Ord

    impl Ord for Item {
        fn cmp(&self, other: &Self) -> Ordering {
            match self.offset {
                b if b > other.offset => Ordering::Less,
                b if b < other.offset => Ordering::Greater,
                b if b == other.offset => Ordering::Equal,
                _ => Ordering::Equal, // ?not sure why compiler needs this
            }
        }
    }
    

    现在 BinaryHeap 返回 Item 从最小到最大。既然这不是预期的API,那么这是一种不正确的或容易出错的模式吗?

    我意识到 LinkedList pop_front 方法,但我需要在插入时对列表进行排序。这是更好的解决方案吗?

    1 回复  |  直到 5 年前
        1
  •  15
  •   Tim Vermeulen    5 年前

    在堆中反转类型的顺序是可以的。但是,您不需要实现自己的订单反转。相反,使用 std::cmp::Reverse Ordering::reverse 视情况而定。

    Ord :

    impl Ord for Item {
        fn cmp(&self, other: &Self) -> Ordering {
            self.offset.cmp(&other.offset).reverse()
        }
    }
    

    BinaryHeap

    use std::{cmp::Reverse, collections::BinaryHeap};
    
    fn main() {
        let mut a: BinaryHeap<_> = vec![1, 2, 3].into_iter().collect();
        if let Some(v) = a.pop() {
            println!("Next is {}", v);
        }
    
        let mut b: BinaryHeap<_> = vec![1, 2, 3].into_iter().map(Reverse).collect();
        if let Some(Reverse(v)) = b.pop() {
            println!("Next is {}", v);
        }
    }
    
    Next is 3
    Next is 1
    

    是[是] LinkedList ]更好的解决方案?

    99.9%的情况下,链接列表是 更好的解决方案。