我正在寻找一个Voronoi曲面细分算法的二元搜索树(Fortune的算法;本身就是一个非常重要的任务,也就是这个问题),所以当然,我想我会看看Boost。
Boost有Intrusive
头文件,它似乎包含大量BST(例如AVL,Splay树和Scapegoat树 - 哈,我必须在那里确定那个名字!)并且最初视线看起来就像我需要的那样。
1:我错过了什么或者无法直接访问树的根节点?
2: AVL树是否适合财富算法海滩线结构?
该死的,我觉得这很容易。更新:也许最好说明我的目标:我想实施抛物线搜索,它是财富算法的一部分,检测新网站的部分,我们需要直接在头顶上找到抛物线。我以为我会从根开始遍历树,以便找到正确的弧。
答案 0 :(得分:3)
iterator begin();
const_iterator begin() const;
const_iterator cbegin() const;
基于文档,有点不清楚,但看起来begin()将返回第一个头节点(也称为根节点)。
http://www.dcs.gla.ac.uk/~samm/trees.html
<强>更新强>
#include <iostream>
#include <algorithm>
#include <boost/intrusive/rbtree.hpp>
using namespace boost::intrusive;
struct X : public set_base_hook<optimize_size<true> > {
X(int x) : _x{x} { }
int _x;
friend inline std::ostream& operator<<(std::ostream&, const X&);
friend bool operator<(const X&, const X&);
friend bool operator>(const X&, const X&);
friend bool operator==(const X&, const X&);
};
std::ostream& operator<<( std::ostream& os, const X& x) {
os << x._x;
return os;
}
bool operator<(const X& lhs, const X& rhs) { return lhs._x < rhs._x; }
bool operator>(const X& lhs, const X& rhs) { return lhs._x > rhs._x; }
bool operator==(const X& lhs, const X& rhs) { return lhs._x == rhs._x; }
int main()
{
typedef rbtree<X> tree_t;
tree_t tree;
X x0(0);
X x1(1);
X x2(2);
/*! Output is the same for the following
* X x1(1);
* X x0(0);
* X x2(2);
*/
tree.insert_unique(x1);
tree.insert_unique(x0);
tree.insert_unique(x2);
std::for_each(
tree.begin(), tree.end(),
[](const X& xx) { std::cout << "x: " << xx << std::endl; });
}
输出
x:0 x:1 x:2
我注意到push_back / push_front没有调用树重新排序。也许我在文档中错过了它。
答案 1 :(得分:1)
最后我实现了自己的AVL树。 Voronoi算法的复杂性似乎要求它,并且Boost版本无法访问节点,无论如何(如果我错了,请指出它;考虑到Boost的默默无闻,它是可能的)。
AVL树似乎完美地完成了这项工作。
答案 2 :(得分:0)
实际上查找root比听起来容易。
首先,你必须编写通常的东西来使用boost :: intrusive之类的钩子等等。
boost::intrusive::avltree<Object> avl;
如果要在任何boost :: intrusive中查找节点,则必须使用find()。 现在,find()函数需要一个overloaded()运算符,它基本上检查$ a> b $或$ b&lt; a $(非常类似于strcmp的布尔输出),您希望此运算符在根节点处失败,因此它将返回根作为结果。这样做的一种方法是
class RootComp{
bool operator () (const Object &a, const int b) const {
return false;
}
bool operator () (int b, const Object &a) const{
return false;
}
};
然后使用find()很简单:
int data=0;
boost::intrusive::avltree<Object>::iterator it = avl.find(data, RootComp());
if( it != avl.end() ){
//*it is the root
}else{
// the tree is empty
}
答案 3 :(得分:0)
Boost.Intrusive树状容器有一个root()成员,如果没有根节点,则返回根节点或end()的迭代器。这些功能很久以前就已经发生了。以下提交:
https://github.com/boostorg/intrusive/commit/6d38384e369697894bb71fb81132ad60b796c70c
记录这些功能,因此它们现在是正式的。以下代码显示了如何使用它:
#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;
}