Binary Tree pre-order middle-order post-order traversal (of course not recursive !), Binary Tree Recursion
The three traversal methods of Binary Trees have always been an interview question. It is the simplest way to test a person's understanding of recursion to write three traversal methods, A deeper understanding of recursion is to use Loop Simulation to simulate recursion (that is, to convert recursive code into non-recursive Code). Stack is required to implement such a thing, it may be said that the stack structure is more compatible with the function Stack's push-in and pop-up, better understanding.
The three recursive traversal methods are pre-order traversal, middle-order traversal, and post-order traversal. After recursive writing is considered, non-recursive writing is more difficult;
- Because pre-order traversal accesses the root node first, it accesses the node and then the left and right children. Previously, the recursive method was used. stack frame simulation can be implemented using stacks,Because the left node is accessed first, the left node should be added to the stack after the right node,B is not difficult to write the following code
1 void PreOrder_NonR() 2 3 { 4 5 if (_root == NULL ) 6 7 { 8 9 return;10 11 }12 13 stack<BinaryTreeNode <T>*> s;14 15 s.push(_root);16 17 while (!s.empty())18 19 {20 21 BinaryTreeNode<T >* top = s.top();22 23 cout << top->_data << " " ;24 25 s.pop();26 27 if (top->_right)28 29 {30 31 s.push(top->_right);32 33 }34 35 if (top->_left)36 37 {38 39 s.push(top->_left);40 41 }42 43 }44 45 cout << endl;46 47 }
- You can use recursive thinking to traverse the middle order,Because the central Traversal method is to access the root node after accessing the left subtree, after accessing the root node, the right subtree enters the right subtree. The right subtree is equivalent to a new root node, so we should immediately press the right child into the stack after accessing the root node.And then enter the loop to write the following code
1 void InOrder_NonR() 2 3 { 4 5 stack<BinaryTreeNode <T>*> s; 6 7 BinaryTreeNode<T > *cur = _root; 8 9 while (cur || !s.empty())10 11 {12 13 while (cur)14 15 {16 17 s.push(cur);18 19 cur = cur->_left;20 21 }22 23 if (!s.empty())24 25 {26 27 BinaryTreeNode<T > *top = s.top();28 29 cout << top->_data << " " ;30 31 s.pop();32 33 cur = top->_right;34 35 }36 37 }38 39 cout << endl;40 41 }
- Post-order traversal accesses the Left and Right Subtrees first, so when the left child leaves the stack, the nodes in the next stack (that is, the root node) cannot be accessed immediately. You need to consider several situations, if the right child is empty at this moment, you can access it. If a child is not empty at this time, you need to consider whether the right child has been accessed. If yes, you can access the root node. Otherwise, you must first access the right subtree and then access the root node. You can use a variable to save the node that was previously accessed,Write the following code:
1 void PostOrder_NonR() 2 3 { 4 5 stack<BinaryTreeNode <T> *> s; 6 7 BinaryTreeNode<T >* PreVisited = NULL; 8 9 BinaryTreeNode<T >* cur = _root;10 11 while (cur || !s.empty())12 13 {14 15 while (cur)16 17 {18 19 s.push(cur);20 21 cur = cur->_left;22 23 }24 25 BinaryTreeNode<T > *top = s.top();26 27 if (top->_right == NULL || PreVisited == top->_right)28 29 {30 31 cout << top->_data << " " ;32 33 s.pop();34 35 PreVisited = top;36 37 }38 39 else40 41 {42 43 cur = top->_right;44 45 }46 47 }48 49 cout << endl;50 51 }
This is what I derived from my notes. It turns out how indentation turns into this...