我正在寻找一种模拟树的方法,每个节点有一个任意数量的子节点。
这个答案建议使用Boost Graph Library来完成这项任务:
What's a good and stable C++ tree implementation?
我需要执行的主要操作是树的遍历函数(preorder,children,leafs)及其子树。我还需要从孩子们那里收集数据的函数。
BGL是否是正确的选择,如何实现一个简单树的前序遍历?在文档中,我只能找到常规图表的信息。
编辑:我也知道tree.hh
库,但其许可似乎并不适合所有人。
答案 0 :(得分:4)
我对这棵树做了改进。顶点和边缘迭代器现在都包裹在外观中。如果我做出更多重大更改,我会发布它们。我曾经使用过tree.hh一段时间用于一个小项目,但并不是很喜欢它。我将替换它以查看它还需要什么。
// Parallax
var layerBg = document.querySelector('.js-layer-bg');
var layerText = document.querySelector('.js-layer-text');
var sectionIntro = document.getElementById('section-intro');
var scrollPos = window.pageYOffset;
var layers = document.querySelectorAll('[data-type=\'parallax\']');
var parallax = function() {
for (var i = 0, len = layers.length; i < len; i++) {
var layer = layers[i];
var depth = layer.getAttribute('data-depth');
var movement = (scrollPos * depth) * -1;
var translate3d = 'translate3d(0, ' + movement + 'px, 0)';
layer.style['-webkit-transform'] = translate3d;
layer.style.transform = translate3d;
}
};
window.requestAnimationFrame(parallax);
window.addEventListener('scroll', function() {
// Parallax layers
scrollPos = window.pageYOffset;
window.requestAnimationFrame(parallax);
// Animate text layers
var vhScrolled = Math.round(window.pageYOffset / window.innerHeight * 100);
if (vhScrolled > 100 && layerText.classList.contains('is-hidden')) {
layerText.classList.remove('is-hidden');
} else if (vhScrolled <= 100 && !layerText.classList.contains('is-hidden')) {
layerText.classList.add('is-hidden');
}
});
答案 1 :(得分:1)
Boost Graph库是功能强大的库。但就我而言,在你的情况下,这是太多的工具。您的操作很简单。您不需要复杂的图算法,如(搜索路径,图形分区等)。此外,您的案例中的主要数据结构只是树(不是GENERAL图!)。在这种情况下,您可以尝试使用以下代码:
#include <iostream>
#include <list>
#include <functional>
#include <memory>
// TODO: (dev) T should not be pointer type, in such case you will get memory leak!
// Wrap it with unique_ptr, or create other specialization, or keep key in unique_ptr
template <typename T>
class Node
{
public:
typedef T key_type;
typedef std::list<Node<T>*> nodes_type;
Node(key_type key) :
m_key(key)
{
}
template <typename Func>
void process_preorder(Func f) const
{
f(m_key);
for (nodes_type::const_iterator loc = m_nodes.begin(); loc != m_nodes.end(); ++loc)
(*loc)->process_preorder(f);
}
template <typename Func>
void process_children(Func f) const
{
for (nodes_type::const_iterator loc = m_nodes.begin(); loc != m_nodes.end(); ++loc)
f((*loc)->m_key);
}
template <typename Func>
void process_leafs(Func f) const
{
if (m_nodes.empty())
f(m_key);
for (nodes_type::const_iterator loc = m_nodes.begin(); loc != m_nodes.end(); ++loc)
(*loc)->process_leafs(f);
}
Node<T>& add_child(key_type key)
{
Node<T>* new_node = new Node(key);
m_nodes.push_back(new_node);
return *new_node;
}
~Node()
{
std::cout << "Deletion node with key: " << m_key << std::endl;
// Children deletion
while (!m_nodes.empty())
{
delete m_nodes.back();
m_nodes.pop_back();
}
}
private:
key_type m_key;
nodes_type m_nodes;
};
int main()
{
{
typedef Node<int> node_type;
std::unique_ptr<node_type> n = std::make_unique<node_type>(0);
{
for (int i = 1; i <= 3; ++i)
{
node_type& current_child = n->add_child(i);
for (int j = 1; j <= 3; ++j)
current_child.add_child(i * 10 + j);
}
}
std::function<void(node_type::key_type)> printer = [](const node_type::key_type key) {std::cout << key << std::endl;};
std::cout << "Printing via preorder" << std::endl;
n->process_preorder(printer);
std::cout << "Printing children of node with key: " << std::endl;
n->process_children(printer);
std::cout << "Printing leafs" << std::endl;
n->process_leafs(printer);
}
int i = 0;
std::cin >> i;
return 0;
}