gpt4 book ai didi

c++ - 迭代 std::set 如何返回排序结果

转载 作者:可可西里 更新时间:2023-11-01 17:39:02 35 4
gpt4 key购买 nike

容器std::set(或std::map)是STL提供的一种数据结构。在几乎所有的编译器中,它都被实现为一个 R&B 树,保证了 log(n) 的插入、查找和删除时间。

https://en.wikipedia.org/wiki/Red%E2%80%93black_tree

在红黑树中,元素根据存储元素的“less”运算符进行排序。所以基本上如果一个根是 N + 1 , N 将在左子树上,而 N + 2 将在右子树上,这个顺序将由 less 运算符决定。

我的问题是在执行以下代码时:

 set<unsigned long>::iterator it;
for (it = myset.begin(); it != myset.end(); it++) {
cout << *it;
}

元素按排序顺序返回。考虑到底层数据结构是红黑树这一事实,这怎么可能呢?是否存储了一个单独的链表以便能够从最左边的子树迭代到最右边的子树?如果不是,这个使用 R&B 树的实现背后的机制是什么?

最佳答案

我们可以通过查看源代码(在本例中为 libstdc++ 5.2.1)找到明确的答案。这是树节点的样子:

// <libstdc++>/include/bits/stl_tree.h
struct _Rb_tree_node_base {
typedef _Rb_tree_node_base* _Base_ptr;

_Rb_tree_color _M_color;
_Base_ptr _M_parent;
_Base_ptr _M_left;
_Base_ptr _M_right;

// ...
}

因此每个节点都包含一种颜色,以及指向其父节点及其左右子节点的指针。递增实现为:

//  <libstdc++>/include/bits/stl_tree.h
struct _Rb_tree_iterator {
_Self& operator++() {
_M_node = _Rb_tree_increment(_M_node);
return *this;
}

// ...

private:
_Base_ptr _M_node;
};

实际增量不再在公共(public)头文件中,而是在库的编译部分:

// <libstdc++>/src/c++98/tree.cc
static _Rb_tree_node_base* local_Rb_tree_increment(_Rb_tree_node_base* __x) throw ()
{
if (__x->_M_right != 0) {
__x = __x->_M_right;
while (__x->_M_left != 0)
__x = __x->_M_left;
} else {
_Rb_tree_node_base* __y = __x->_M_parent;
while (__x == __y->_M_right) {
__x = __y;
__y = __y->_M_parent;
}
if (__x->_M_right != __y)
__x = __y;
}
return __x;
}

因此,最终,它是树遍历的教科书式实现:迭代器持有指向“当前”节点的指针,为了到达树中向上移动的下一个节点,只要它来自正确的 child .如果它来自左 child ,它将下降到右 child 的最左边的 child 节点。

关于c++ - 迭代 std::set 如何返回排序结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33526444/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com