1

C++ std::priority_queue 只需要一个部分顺序。但是如果它的实现是一个二叉堆,它是如何工作的呢?例如:假设我们有一个偏序集( {a, b, c, x}, {c < b, b < a, c < a} ),与, ,x无关。那么最大堆是:abc

layer 1:    x
layer 2:  b   x
layer 3: x x a c

弹出操作后,以教科书常见的方式,即替换根c并减小大小1。然后我们需要在根处对下面的树进行heapify:

layer 1:    c
layer 2:  b   x
layer 3: x x a

我们将交换cbas c < b,不是吗?什么?我们仍然没有一个有效的堆,因为b < a. 但b不能“看到” a

4

1 回答 1

7

priority_queue比较器定义严格、弱排序的要求是(C++ 标准的第 23.6.4 节) 。后者在 §25.4/4 中定义如下:

术语 strict 指的是对所有 x 的非自反关系(!comp(x, x))的要求,而术语 weak 指的是不如全序强但比偏序强的要求. 如果我们将 equiv(a, b) 定义为 !comp(a, b) && !comp(b, a),那么要求 comp 和 equiv 都是传递关系:

— comp(a, b) && comp(b, c) 意味着 comp(a, c)

— equiv(a, b) && equiv(b, c) 隐含 equiv(a, c) [ 注意:在这些条件下,可以证明

i) equiv 是等价关系

ii) comp 在由 equiv 确定的等价类上引入明确定义的关系

iii) 诱导关系是严格的全序。——尾注]

换句话说,比较器定义的关系不必是全部的,但它必须相对于由假设关系定义的等价类是全部的,假设关系equiv将所有不小于或大于每个元素的元素定义为相等其他。

用更简单的术语来说,比较关系未涵盖的任何元素都将被视为相等。

于 2012-09-14T07:20:55.690 回答