为什么 BinaryHeap 需要 Ord?

Why does BinaryHeap require Ord?

我使用标准 BinaryHeap 作为算法的一部分,我需要检索最大的对象(通过最大的一些定义)。有可能两个不等价的元素都同样大(因此它们在二叉堆中的相对顺序无关紧要)——例如,我可能只对多字段结构的单个字段排序感兴趣。

因此,让我的类型实现 OrdEq 会有些不寻常。相反,我应该只实现 PartialOrdPartialEq。但是,唉,BinaryHeap 要求它的元素是 Ord!为什么会这样,对这些类型使用 BinaryHeap 最惯用的方法是什么?

(顺便说一句,在 C++ 中,在这种情况下我很容易编写自定义比较器类型,并在比较器类型上模板化优先级队列。所以我不认为我想做的是数学上的或者算法错误。)

PartialOrd 为您提供非对称和传递排序,即 a < b 表示 !(a > b)a < b && b < c 表示 a < cPartialOrd 要求所有元素实际上都具有有意义的顺序,这就是为什么 PartialOrd::partial_cmp returns 和 Option<Ordering> 其中None 表示“我不知道”(注意这不会影响上述要求)。

二叉堆需要对其元素进行全排序,但是,因为二叉堆必须具有 属性 即“存储在每个节点中的键大于等于 (≥) 或小于根据某种总顺序,大于或等于 (≤) 节点子节点中的键。” (通过维基百科直接引用)。

只有 Ord 为您提供非对称、传递和总(恰好是 a < ba == ba > b 之一)排序。总订单的要求导致 Ord::cmp 返回 Ordering,而不是 Option<Ordering>,因为 None-case 是不允许的。

编写 PartialOrdOrd 的特定实现并不少见,以防您需要特定的行为。还有 educe crate,它允许您导出更具体的 PartialOrdOrd 版本,其中某些字段被忽略。