为什么 BinaryHeap 需要 Ord?
Why does BinaryHeap require Ord?
我使用标准 BinaryHeap
作为算法的一部分,我需要检索最大的对象(通过最大的一些定义)。有可能两个不等价的元素都同样大(因此它们在二叉堆中的相对顺序无关紧要)——例如,我可能只对多字段结构的单个字段排序感兴趣。
因此,让我的类型实现 Ord
和 Eq
会有些不寻常。相反,我应该只实现 PartialOrd
和 PartialEq
。但是,唉,BinaryHeap
要求它的元素是 Ord
!为什么会这样,对这些类型使用 BinaryHeap
最惯用的方法是什么?
(顺便说一句,在 C++ 中,在这种情况下我很容易编写自定义比较器类型,并在比较器类型上模板化优先级队列。所以我不认为我想做的是数学上的或者算法错误。)
PartialOrd
为您提供非对称和传递排序,即 a < b
表示 !(a > b)
而 a < b && b < c
表示 a < c
。 PartialOrd
不 要求所有元素实际上都具有有意义的顺序,这就是为什么 PartialOrd::partial_cmp
returns 和 Option<Ordering>
其中None
表示“我不知道”(注意这不会影响上述要求)。
二叉堆需要对其元素进行全排序,但是,因为二叉堆必须具有 属性 即“存储在每个节点中的键大于等于 (≥) 或小于根据某种总顺序,大于或等于 (≤) 节点子节点中的键。” (通过维基百科直接引用)。
只有 Ord
为您提供非对称、传递和总(恰好是 a < b
、a == b
或 a > b
之一)排序。总订单的要求导致 Ord::cmp
返回 Ordering
,而不是 Option<Ordering>
,因为 None
-case 是不允许的。
编写 PartialOrd
和 Ord
的特定实现并不少见,以防您需要特定的行为。还有 educe
crate,它允许您导出更具体的 PartialOrd
和 Ord
版本,其中某些字段被忽略。
我使用标准 BinaryHeap
作为算法的一部分,我需要检索最大的对象(通过最大的一些定义)。有可能两个不等价的元素都同样大(因此它们在二叉堆中的相对顺序无关紧要)——例如,我可能只对多字段结构的单个字段排序感兴趣。
因此,让我的类型实现 Ord
和 Eq
会有些不寻常。相反,我应该只实现 PartialOrd
和 PartialEq
。但是,唉,BinaryHeap
要求它的元素是 Ord
!为什么会这样,对这些类型使用 BinaryHeap
最惯用的方法是什么?
(顺便说一句,在 C++ 中,在这种情况下我很容易编写自定义比较器类型,并在比较器类型上模板化优先级队列。所以我不认为我想做的是数学上的或者算法错误。)
PartialOrd
为您提供非对称和传递排序,即 a < b
表示 !(a > b)
而 a < b && b < c
表示 a < c
。 PartialOrd
不 要求所有元素实际上都具有有意义的顺序,这就是为什么 PartialOrd::partial_cmp
returns 和 Option<Ordering>
其中None
表示“我不知道”(注意这不会影响上述要求)。
二叉堆需要对其元素进行全排序,但是,因为二叉堆必须具有 属性 即“存储在每个节点中的键大于等于 (≥) 或小于根据某种总顺序,大于或等于 (≤) 节点子节点中的键。” (通过维基百科直接引用)。
只有 Ord
为您提供非对称、传递和总(恰好是 a < b
、a == b
或 a > b
之一)排序。总订单的要求导致 Ord::cmp
返回 Ordering
,而不是 Option<Ordering>
,因为 None
-case 是不允许的。
编写 PartialOrd
和 Ord
的特定实现并不少见,以防您需要特定的行为。还有 educe
crate,它允许您导出更具体的 PartialOrd
和 Ord
版本,其中某些字段被忽略。