如何在boost中访问rbtree的根
基于实例实现了一个红黑树。但是我不明白标题的意思,它是树的根吗?根据描述: 标题节点不仅与根节点保持链接,还与树的最左侧节点保持链接,以启用常数时间开始(),并与树的最右侧节点保持链接,以在与通用集合算法(集合联合等)一起使用时启用线性时间性能如何在boost中访问rbtree的根,boost,Boost,基于实例实现了一个红黑树。但是我不明白标题的意思,它是树的根吗?根据描述: 标题节点不仅与根节点保持链接,还与树的最左侧节点保持链接,以启用常数时间开始(),并与树的最右侧节点保持链接,以在与通用集合算法(集合联合等)一起使用时启用线性时间性能 如何使用头节点访问树的根?这有多复杂?Boost Intrusive的RBTree实现中的头节点包含指向根节点、最左侧和最右侧节点的链接(请参阅) 因此,parent\uu是指向根节点的指针 您可以使用基于该示例中显示的“算法策略”的容器抽象。你会这样写
如何使用头节点访问树的根?这有多复杂?Boost Intrusive的RBTree实现中的头节点包含指向根节点、最左侧和最右侧节点的链接(请参阅) 因此,
parent\uu
是指向根节点的指针
您可以使用基于该示例中显示的“算法策略”的容器抽象。你会这样写,就像我在上一个答案中链接的那样:
下面是一个简单、自包含的示例,演示如何使用基于节点类型构建的实际rbtree
容器(而不仅仅是算法)
请注意,您仍然可以使用容器特性“钻取”并获取节点
struct my_node
{
my_node(int i = 0) :
parent_(nullptr),
left_ (nullptr),
right_ (nullptr),
int_ (i)
{ }
my_node *parent_, *left_, *right_;
int color_;
//data members
int int_;
bool operator<(my_node const& other) const { return int_ < other.int_; }
};
//Define our own rbtree_node_traits
struct my_rbtree_node_traits
{
typedef my_node node;
typedef my_node * node_ptr;
typedef const my_node * const_node_ptr;
typedef int color;
static node_ptr get_parent(const_node_ptr n) { return n->parent_; }
static void set_parent(node_ptr n, node_ptr parent){ n->parent_ = parent; }
static node_ptr get_left(const_node_ptr n) { return n->left_; }
static void set_left(node_ptr n, node_ptr left) { n->left_ = left; }
static node_ptr get_right(const_node_ptr n) { return n->right_; }
static void set_right(node_ptr n, node_ptr right) { n->right_ = right; }
static color get_color(const_node_ptr n) { return n->color_; }
static void set_color(node_ptr n, color c) { n->color_ = c; }
static color black() { return color(0); }
static color red() { return color(1); }
};
#include <boost/intrusive/link_mode.hpp>
namespace bi = boost::intrusive;
struct my_value_traits
{
typedef my_rbtree_node_traits node_traits;
typedef node_traits::node value_type;
typedef node_traits::node_ptr node_ptr;
typedef node_traits::const_node_ptr const_node_ptr;
typedef value_type* pointer;
typedef value_type const* const_pointer;
static const bi::link_mode_type link_mode = bi::link_mode_type::normal_link;
static node_ptr to_node_ptr (value_type &value) { return &value; }
static const_node_ptr to_node_ptr (const value_type &value) { return &value; }
static pointer to_value_ptr (node_ptr n) { return n; }
static const_pointer to_value_ptr (const_node_ptr n) { return n; }
};
#include <boost/intrusive/rbtree.hpp>
using mytree = bi::rbtree<my_node, bi::value_traits<my_value_traits> >;
#include <iostream>
#include <vector>
int main() {
std::vector<my_node> storage { {1}, {3}, {4}, {2}, {3}, };
mytree container;
container.insert_equal(storage.begin(), storage.end());
// NOW for the "have your cake and eat it too" moment:
for (my_node& n : container) {
std::cout << n.int_
<< " (parent: " << n.parent_ << ")"
<< " (left: " << n.left_ << ")"
<< " (right: " << n.right_ << ")"
<< "\n";
}
}
Boost.Intrusive树的结构在bstree_算法()的文档中进行了解释。还解释了“标题”节点: “在树的顶部专门使用一个节点。此节点的父指针指向树的根。其左指针指向树中最左边的节点,右指针指向最右边的节点。此节点用于表示结束迭代器。” 因此,您可以使用以下方式访问根节点:
root = rbtree_algorithms::get_parent(header);
如果您正在使用值特征构建自己的容器,正如sehe所解释的,因为提交:
基于树的容器有一个root()函数,该函数以O(1)的复杂度将迭代器返回到根节点(如果不存在,则返回end()),这可能更易于使用:
#include <boost/intrusive/set.hpp>
#include <cassert>
using namespace boost::intrusive;
struct MyClass : public set_base_hook<>
{
friend bool operator<(const MyClass&, const MyClass&)
{ return true; }
};
int main()
{
set<MyClass> set;
//end() is returned when the tree is empty
assert(set.root() == set.end() );
//insert myobject, must be root
MyClass myobject;
set.insert(myobject);
assert(&*set.root() == &myobject);
//erase and check root is again end()
set.erase(set.root());
assert(set.croot() == set.cend());
return 0;
}
#包括
#包括
使用名称空间boost::intrusive;
struct MyClass:public set\u base\u hook
{
friend bool运算符“Iv实现了红黑树”//您可能应该共享代码好吧,我的代码与示例中的代码一样。我只是在其中添加了一些详细信息。我的问题是,我不知道标题是否有指向根的链接,或者我应该指定它?您能更清楚地说明您的答案中添加了哪些不在我的答案中的内容吗?我想您也漏掉了一些单词(什么提交?)感谢您的评论。我试图进一步解释根节点是什么(第一个问题),并补充说,最近的提交允许直接从入侵容器中获取根节点(第二个问题的替代方案)以及该操作的O(1)复杂性(第三个问题).我已经编辑了答案,以包含缺少的单词和链接。谢谢。这是一个有价值的补充!
#include <boost/intrusive/set.hpp>
#include <cassert>
using namespace boost::intrusive;
struct MyClass : public set_base_hook<>
{
friend bool operator<(const MyClass&, const MyClass&)
{ return true; }
};
int main()
{
set<MyClass> set;
//end() is returned when the tree is empty
assert(set.root() == set.end() );
//insert myobject, must be root
MyClass myobject;
set.insert(myobject);
assert(&*set.root() == &myobject);
//erase and check root is again end()
set.erase(set.root());
assert(set.croot() == set.cend());
return 0;
}