用于迭代后序遍历的堆栈中的节点是否始终是祖先,而某些节点没有其他节点?

时间:2011-07-24 06:12:19

标签: tree traversal iteration

如果我需要在具有某个给定属性的某个节点上打印到root的路径上的所有节点。 我可以使用迭代后序遍历来查找节点然后打印整个堆栈吗?

编辑:有没有其他方法可以跟踪祖先?这不是一个bst。

2 个答案:

答案 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中,如果您发现该节点是您正在搜索的节点,那么堆栈中的元素就是该节点的父节点。