Non-recursive binary tree traversal of thought

In the latest learning data structure to learn from the code book in the sample to an abstract thinking, learning binary record some insights

Preorder

Preorder relatively simple, when I opened consider implementation of the four cases

  1. Left child and right child is null && empty
    access the root node, then the stack
  2. Left child is not null && empty right child
    access to the root node, and then continue to visit the children left
  3. Null && left child and right child is not empty
    access the root node, right child stack, the stack
  4. Children are not left empty right child is not null &&
    access the root node, the stack right child, left the children continue to visit
template<typename Elemtype>
template<typename Fun>
bool BiTree<Elemtype>::PreOrderTraverse(Fun &visit){
  Stack<BiTNode<Elemtype>*> S;
  InitStack<bool,BiTNode<Elemtype>*>(S);
  BiTNode<Elemtype> *p = root;
  while (p != nullptr)
  {
      visit(p);
      if(p->rChrilde != nullptr) 
          Push<bool,BiTNode<Elemtype>*>(S,p->rChrilde);

      if(p->lChrilde != nullptr) 
          p = p->lChrilde;
      else
          //如果栈空Pop()返回false,用于判断栈空结束循环
          if(!Pop<bool,BiTNode<Elemtype>*>(S,p))
              p = nullptr;
  }
  return true;
}

This conventional approach, I believe we have a different implementation, but the examples (University Press of data structures (c language version)) on a very simple book

template<typename Elemtype>
template<typename Fun>
bool BiTree<Elemtype>::PreOrderTraverse(Fun &visit){
Stack<BiTNode<Elemtype>*> S;
InitStack<bool,BiTNode<Elemtype>*>(S);
BiTNode<Elemtype> *p = root;
while (p || !StackEmpty<bool,BiTNode<Elemtype>*>(S)){
    if (p != nullptr){
        //存入栈中  
        Push<bool,BiTNode<Elemtype>*>(S,p);
        //访问节点
        visit(p);
        //遍历左子树  
        p = p->lChrilde;
     }
    else{
        //退栈
        Pop<bool,BiTNode<Elemtype>*>(S,p); 
        //访问右子树  
        p = p->rChrilde;
    }
  }
return true;
}

The idea is very simple conclusion is that, left to go, nowhere to go right
this way, the issue was abstract became both cases

  1. The current node is not empty
    go left
  2. The current node is empty
    to the right child of the root node of the current node to go
    this whole situation simply judge very much, will have a problem abstract set up four cases both cases
    it is also recursive ideas into circulation to achieve

Preorder

Preorder now preorder thinking almost the same, just visit it at different times

template<typename Elemtype>
template<typename Fun>
bool BiTree<Elemtype>::PreOrderTraverse(Fun &visit){
Stack<BiTNode<Elemtype>*> S;
InitStack<bool,BiTNode<Elemtype>*>(S);
BiTNode<Elemtype> *p = root;
while (p || !StackEmpty<bool,BiTNode<Elemtype>*>(S)){
    if (p != nullptr){
        //存入栈中  
        Push<bool,BiTNode<Elemtype>*>(S,p);
        //遍历左子树  
        p = p->lChrilde;
     }
    else{
        //退栈
        Pop<bool,BiTNode<Elemtype>*>(S,p); 
        //访问节点
        visit(p);
        //访问右子树  
        p = p->rChrilde;
    }
  }
return true;
}

Postorder

Postorder contrast lot of complexity, because the order is left -> Right -> root
because you left the child at the time of access, can not know a child has the right, and the right child has no children
I checked a little on some of Baidu most implementations as follows

The first idea: for any node P, its stack, and then the search has been down along the left subtree, until the search to no left child node, then the node appears in the top of the stack, but this when the stack and can not be accessed, so its right child also be accessed. Therefore, the same processing subsequent to its right subtree according to the same rules, which when finished accessing right child, the node appeared in the top of the stack, this time it can be accessed and the stack. This ensures that the correct access order. As can be seen, in this process, each node will appear twice in the top of the stack, only the second occurrence at the top of the stack, in order to access it. Requiring a multiple variable set identifies whether the node is the first time the top of the stack.

The second idea: to ensure that the root can be accessed after the children left and right child access, so for any node P, the first of its stack. Left child and right child if P does not exist, you can access it directly; or there is a left child or right child P, but the kids left and right children have been visited, you can also access the node directly. If not the above two cases, then P is left child and right child of the stack in sequence, thus ensuring each time taking the top element, is accessed at the front left child and right child, right child and left child node in the root the previous point is accessed. (Note the order of his stack, and on a method not the same, not all of the left subtree and then turn right subtree stack.)

Reprinted from https://www.cnblogs.com/SHERO-Vae/p/5800363.html

But I think a slightly different implementations of
fact, the order will in turn see (because the stack is a last-out) root -> Right -> left
there did not feel very familiar? Then another way to root -> Left -> Right
Yes, in fact, is the priority of the right child preorder traversal, will visit about order transposing the child, you can get such a stack
analogy (soul drawing)

such priority right child preorder traversal results 1,576,243
in turn is 3426751
is not that postorder results yet

  
template<typename Elemtype>
template<typename Fun>
bool BiTree<Elemtype>::PostOrderTraverse(Fun &visit){
Stack<BiTNode<Elemtype>*> S,tmp;
InitStack<bool,BiTNode<Elemtype>*>(S);
InitStack<bool,BiTNode<Elemtype>*>(tmp);
BiTNode<Elemtype> *p = root;
  while (p || !StackEmpty<bool,BiTNode<Elemtype>*>(S)){
      if (p != nullptr){
          //存入栈中  
          Push<bool,BiTNode<Elemtype>*>(S,p);
          Push<bool,BiTNode<Elemtype>*>(tmp,p);
          //遍历右子树  
          p = p->rChrilde;
       }
      else{
          //退栈
          Pop<bool,BiTNode<Elemtype>*>(S,p);
          //访问左子树  
          p = p->lChrilde;
      }
  }
  while (!StackEmpty<bool,BiTNode<Elemtype>*>(tmp))
  {
      Pop<bool,BiTNode<Elemtype>*>(tmp,p);
      visit(p);
  }
  
  return true;
}

This allows a relatively simple implementation of non-recursive postorder traversal

to sum up

The so-called algorithm only reflects the feeling of thinking, or judgment of abstract scenes, if the problem can abstract good, then it will reduce the difficulty of solving the many, many

btw: I'm still learning c ++ among the template might learn is not particularly good, if that is seeking to achieve complex light spray. . .

Guess you like

Origin www.cnblogs.com/passbysomeone/p/11961930.html