std::map 的排序是如何实现的

How is the ordering of std::map achieved?

本文关键字:实现 何实现 map 排序 std      更新时间:2023-10-16

我们可以从几个来源看到std::map是使用红黑树实现的。我的理解是,这些类型的数据结构不以任何特定的顺序保存它们的元素,而只是保持BST属性和高度平衡要求。

那么,为什么 map::begin 是常量时间,并且我们能够迭代一个有序序列呢?

std::map内部维护 BST 的前提开始(这不是标准的严格要求,但大多数库可能会这样做,就像一棵红黑树(。

在BST中,要找到最小的元素,您只需沿着左边的分支直到到达一个叶子,即O(log(N((。但是,如果你想在恒定的时间内交付"begin(("迭代器,那么在内部跟踪最小的元素是非常简单的。每次插入导致最小的元素发生变化时,您都会更新它,仅此而已。当然,这是内存开销,但这是一种权衡。

可能还有其他方法可以挑出最小的元素(例如故意保持根节点不平衡(。无论哪种方式,都不难做到。

要遍历

"有序"序列,您只需按顺序遍历树。从最左边的叶节点开始,你去(上(,(右(,(上,上(,(右(,...等等..这是一组简单的规则,并且易于实现,只需查看我不久前编写的简单BST顺序迭代器的快速实现即可。在执行按顺序遍历时,您将按正确的顺序从最小到最大访问每个节点。换句话说,它只是给你一种错觉,即"数组"被排序了,但实际上,正是遍历使它看起来像是被排序的。

红黑树的平衡属性允许您以 O(log N( 成本在树中的任何位置插入节点。 对于典型的std::map实现,容器将保持树的排序,并且每当插入新节点时,请将其插入正确的位置以保持树的排序,然后重新平衡树以维护红黑属性。

所以不,红黑树本质上不是排序的。

RB 树是二叉搜索树。二叉搜索树不一定以任何特定顺序存储其元素,但您始终可以获得无序遍历。我不确定 map::begin 如何保证恒定时间,我认为这涉及始终记住最小元素的路径(通常是 O(log(n(((。