如果我需要在具有某个给定属性的某个节点上打印到root的路径上的所有节点。 我可以使用迭代后序遍历来查找节点然后打印整个堆栈吗?
编辑:有没有其他方法可以跟踪祖先?这不是一个bst。答案 0 :(得分:0)
跟踪图中祖先的一种方法是让每个节点都存储指向其父节点的指针。这样,从任何节点开始,只需迭代地跟随父指针即可返回到根节点。走这样一条路径的运行时间是O(d),其中d是节点的深度。如果你知道一个事实,你将经常从节点走到根,这种方法是值得考虑的。
至于您的原始问题,是的,您可以使用迭代后序遍历来查找从任何节点返回到根的路径。堆栈上的任何节点都将是节点本身或某些祖先,它们将按正确的顺序排列。然而,这比仅存储父指针的方法效率低得多。查找节点可以在具有n个节点的树中花费O(n)时间,该节点相对于上面概述的O(d)解决方案与树的大小相比很差。
编辑:我误解了迭代后序的含义。这也可以通过递归后序遍历来轻松完成,您可以通过调用链向下传递堆栈。这是C ++中的一个例子:
void RecSearchWithHistory(Node* curr, vector<Node*>& history) {
// Base case: if the node is NULL, we're done.
if (curr == NULL) return;
// Mark that we've been to the current node.
history.push_back(curr);
// If we found what we are looking for, we now have the path
// to the root available!
if (/* some predicate */)
/* ... use history ... */
// Visit both children (assuming this is a binary tree; the
// generalization fir multi-way trees is easy.
RecSearchWithHistory(curr->left, history);
RecSearchWithHistory(curr->right, history);
// Finally, pop the stack since we are done using this node.
history.pop_back();
}
答案 1 :(得分:0)
我认为这是可能的,这是我的代码:
Node* getRightSibling(Node* parent,Node* child){
if(parent->right == child)
return NULL;
else if(parent->left == child)
return parent->right;
return NULL;
}
void iterativePostOrder(Node* root) {
stack<Node*> nodeStack;
Node* current = root;
while (true) {
if(current != null){
nodeStack.push(current);
if(current->left != NULL) //push left sub-tree
current = current->left;
else if(current->right != NULL) //push right sub-tree
current = current->right;
continue;
}
if(nodeStack.empty()) return;
current = nodeStack.pop();
visitNode(current);
Node* parent = nodeStack.top();
Node* rightSibling = getRightSibling(parent,current);
if(rightSibling == null) {
//two case:
// 1. parent has no right child
// 2. current is the parent's right child, we complete access
// right sub-tree.
//in either case we need access parent, and because parent is at
//the top of Stack, so:
current = NULL;
}else{
// we need start to access right-subtree.
current = rightSibling;
}
}
我只将搜索路径中的节点推送到堆栈中,因此在visitNode中,如果您发现该节点是您正在搜索的节点,那么堆栈中的元素就是该节点的父节点。