现在需要寻找链式二叉树节点元素为x的所有祖先并输出。
思路
利用栈进行后序遍历,设立两个栈in 和 out,in用来遍历二叉树,out用来存储输出的信息,仅仅是为了将遍历的节点存起来最后一起输出。
利用栈进行后序遍历的步骤如下:
- 节点p从根节点开始一直往右下走并进栈,直到null
- 若p为null,则令p = stack.top().left,栈顶的那个元素已经没用了,所以并弹出一个元素。
- 若p为null而且栈为空,说明遍历完成。
struct Node {
int data{0};
Node *l{nullptr};
Node *r{nullptr};
};
void posOrder_stack(Node *root) {
stack<Node *> 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<Node *> 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;
}