树遍历:从叶到叶,再到根

问题描述

即使我编程了很长一段时间,我也不得不承认我正在努力想出一个算法,从叶子到叶子然后向上遍历树,就像这样(遍历内部节点的方向实际上并不重要,如有必要,可以切换 45):

enter image description here

我目前的设置看起来像这样(尽管我的图可能表明这不是必要的二叉树):

struct Node {
    void *data;
    std::vector<Node*> next;
    std::vector<Node*> prev;
};

struct Tree {
    Node *root;
    
    TreeIterator begin() {
        
        /* Start at the very left leaf */
        Node *left_leaf = root;
        
        while( !left_leaf->next.empty() ) {
            left_leaf = left_leaf->next.first();
        }
        
        return TreeIterator(left_leaf);
    }
    
    TreeIterator end() { return TreeIterator(root); }
};

struct TreeIterator {
    
    TreeIterator(Node *_node) : node(_node) { }
    
    Node* operator*() const { return node; }
    void* operator->() const { return node->data; }
    
    TreeIterator& operator++() const {
        /* Todo: Jump to the next leaf and / or upwards */
        return *this;
    }
    
private:
    Node *node;
};

你可以考虑给我一些提示吗?

解决方法

  1. 制作 BFS
  2. 您从 queue 中取出的每个节点都将推回 vector
  3. 以相反的顺序遍历向量。

基本上是这样的:

queue<Node> q;
vector<Node> answer;
q.push(root);
while(!q.empty())
{
    Node first = q.front();
    answer.push_back(first);
    q.pop();
    for(every NODE reachable from first)
        q.push(NODE);
}
reverse(begin(answer),end(answer));

这只是算法,我已经把最接近的代码放在了我能做到的地方。您现在可以使用向量 answer 制作迭代器逻辑。

您可以使用堆栈代替。要点是:通过在 BFS 中遍历,您正在执行与您要实现的目标相反的顺序。