二叉树寻找节点x的所有祖先

现在需要寻找链式二叉树节点元素为x的所有祖先并输出。

思路

利用栈进行后序遍历,设立两个栈in 和 out,in用来遍历二叉树,out用来存储输出的信息,仅仅是为了将遍历的节点存起来最后一起输出。


利用栈进行后序遍历的步骤如下:

  1. 节点p从根节点开始一直往右下走并进栈,直到null
  2. 若p为null,则令p = stack.top().left,栈顶的那个元素已经没用了,所以并弹出一个元素。
  3. 若p为null而且栈为空,说明遍历完成。
struct Node {
    int data{0};
    Node *l{nullptr};
    Node *r{nullptr};
};
void posOrder_stack(Node *root) {
    stack in, out;
    Node *p = root;
    while (p != nullptr || !in.empty()) {
        if (p == nullptr) p = in.top()->l, in.pop(); //in.top已经没有用了
        else in.push(p), out.push(p), p = p->r;
    }
    while (!out.empty()) {
        cout << out.top()->data << " ";
        out.pop();
    }
    cout << endl;
}

了解了如何利用栈实现二叉树后序遍历,再来看题目,如果遍历的过程中p
节点为x,栈内的剩余的元素就都是她的祖先,注意不是所有的祖先,因为可能有一个祖先被弹出去了,解决方法就是用一个指针来跟踪最近弹出的节点即可。

    void solve(Node *node, int x) {
        stack s;
        Node *p = node;  Node *lastPop = nullptr;
        while (p != nullptr || !s.empty()) {
            if (p == nullptr) lastPop = s.top(), p = s.top()->l, s.pop(); 
            else {
                if (p->data == x) break;
                s.push(p),  p = p->r;
            }
        }
        if (lastPop != nullptr) s.push(lastPop);
        while (!s.empty()) cout << s.top()->data << " ", s.pop();
        cout << endl;
    }

你可能感兴趣的:(数据结构和算法,二叉树)