用C ++建模任意树(带迭代器)

时间:2016-11-25 17:22:33

标签: c++ boost graph tree tree-traversal

我正在寻找一种模拟树的方法,每个节点有一个任意数量的子节点。

这个答案建议使用Boost Graph Library来完成这项任务:

What's a good and stable C++ tree implementation?

我需要执行的主要操作是树的遍历函数(preorder,children,leafs)及其子树。我还需要从孩子们那里收集数据的函数。

BGL是否是正确的选择,如何实现一个简单树的前序遍历?在文档中,我只能找到常规图表的信息。

编辑:我也知道tree.hh库,但其许可似乎并不适合所有人。

2 个答案:

答案 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;
}