[Introduction to algorithms] implements non-recursive traversal of the forward and backward orders of Binary Trees.

Source: Internet
Author: User

[Introduction to algorithms] implements non-recursive traversal of the forward and backward orders of Binary Trees.

The implementation of recursive traversal of Binary Trees is relatively simple, and the code is concise. Instead of recursive traversal, it is not that simple. We need to use another data structure-stack. Binary tree traversal can be divided into three types: pre-order, middle-order, and post-order. They are divided by the root node in the time range, and the root node is first traversed by pre-order traversal, in the middle order, the root node is traversed between the left and right leaf nodes, and in the latter order, the root node is finally traversed. In the three non-recursive traversal modes, neither the forward and middle order are too duplicated, but the latter traversal is relatively difficult.


1. Forward Traversal

Here we traverse in the forward order in the order of "Root-left-right. Here we will study it in the order of "recursion-non-recursion", and so will the next several.

1. Recursive Implementation:

void travel_3(node* r) {if (r != NULL) {cout << r->key << ' ';travel_3(r->left);travel_3(r->right);}}


2. Non-Recursive Implementation:

Non-recursive implementations must use the loop structure. The first traversal requires the root, left, and right, so we must first traverse the left node, however, after traversing the left node, we still need to traverse the right node, and the right node may also have the left subtree to traverse first. Therefore, here we need a stack to save the nodes we have already traversed. After traversing the Left and Right nodes, we can then output the nodes saved in the stack to the stack, then traverse the right subtree of the node, and then bring the node of the right subtree into the loop. In this way, the lower-layer node will be near the top of the stack, and the node will be pushed out of the stack first, in this way, non-recursive pre-order traversal can be achieved. The procedure is as follows:


① Output the value of the node first, and then add the node to the stack


② Then judge whether the left subnode of the node is null. If it is not empty, continue loop ①. If it is empty, it indicates that the node value on this line has been traversed, the node jumps out of the stack to perform the stack operation. As long as the stack is not empty, the node goes out of the stack, and the node is equal to its right sub-node.


③ The traversal ends until all nodes are out of the stack and the loop to the node is empty.


void travel_4(node* r) {if (r != NULL) {stack<node*> s;while (r != NULL || !s.empty()) {while (r != NULL) {cout << r->key << ' ';s.push(r);r = r->left;}if (!s.empty()) {r = s.top();s.pop();r = r->right;}}}}


Ii. Middle-order traversal

The middle-order traversal is similar to the front-order traversal, but only follows the order of "left-root-right.


1. Recursive Implementation:


void travel_1(node* r) {if (r != NULL) {travel_1(r->left);cout << r->key << ' ';travel_1(r->right);}}



2. Non-Recursive Implementation:


In non-recursive implementations, the non-recursive implementations of the pre-sequential traversal are similar. The difference is that the key value position of the output node has changed and is no longer output before the left subnode is obtained, instead, the value of the node is output after the stack is released. This will start from the leftmost node, and then be the root node and the right node.


① Directly add the node to the stack


② Then judge whether the left subnode of the node is empty. If not empty, continue to loop ①; if it is empty, it indicates that all the lines on this line have been in the stack, the node jumps out of the stack and outputs the value of the node as long as the stack is not empty. Then, the node equals the value of its right sub-node and continues the cycle ①.


③ The traversal ends until all nodes are out of the stack and the loop to the node is empty.


void travel_2(node* r) {if (r != NULL) {stack<node*> s;while (r != NULL || !s.empty()) {while (r != NULL) {s.push(r);r = r->left;}if (!s.empty()) {r = s.top();s.pop();cout << r->key << ' ';r = r->right;}}}}



Iii. Post-order traversal

The Recursive Implementation of post-order traversal is no different from the previous one, but non-Recursive Implementation is complicated.


1. Recursive Implementation:


void travel_5(node* r) {if (r != NULL) {travel_5(r->left);travel_5(r->right);cout << r->key << ' ';}}


2. Non-Recursive Implementation:


Here we still need to use the stack, but we need to ensure that the root node must be traversed after the Left and Right subnodes are traversed. How can we ensure this? You can do this as follows:


① Get a node and first import it into the stack. Then it must be located at the bottom of the stack, and later out of the stack.


② If this node does not have left or right subnodes, We can output it directly.


③ If this node has left or right subnodes or both, we can add the Left and Right subnodes to the stack.


④ When we exit the stack, we will find that the Left and Right subnodes always exit the stack before the root node, that is, they are traversed before it, but there is still a problem


⑤ We need to determine whether there are only left nodes, right nodes, or both of them at the exit stack. If we find that the Left and Right subnodes of the stack are empty, we can directly output it. Or, if we find that the previous node on the stack is its left node or right subnode, you can also output it. Otherwise, it indicates that this node is a new node. We need to first import its left and right subnodes into the stack.



Void travel_6 (node * r) {if (r = NULL) {return;} stack <node *> s; node * current_pointer; node * last_pointer; // record the pointer s of the previous loop. push (r); // first press the root node to stack while (! S. empty () {current_pointer = s. top (); // update the current pointer to the new stack top if (current_pointer-> left = NULL & current_pointer-> right = NULL) for each loop) | (last_pointer! = NULL & (last_pointer = current_pointer-> left | last_pointer = current_pointer-> right) {cout <current_pointer-> key <''; s. pop (); last_pointer = current_pointer;} else {if (current_pointer-> right! = NULL) {s. push (current_pointer-> right);} if (current_pointer-> left! = NULL) {s. push (current_pointer-> left );}}}}


Complete code:


Struct node {int key; node * parent; node * left; node * right; node (): key (0), parent (), left (NULL), right (NULL) {} node (int k): key (k), parent (), left (NULL), right (NULL ){}~ Node () {key = 0 ;}}; class bintree {public: node * root; bintree (): root (){}~ Bintree () {// do some cleaning to prevent memory leakage delete_tree (root);} void delete_tree (node * p) {if (p! = NULL) {node * right = p-> right; node * left = p-> left; delete_tree (left); delete p; delete_tree (right); p = NULL; right = NULL; left = NULL; }}/ ** center-order traversal, recursion */void travel_1 (node * r) {if (r! = NULL) {travel_1 (r-> left); cout <r-> key <''; travel_1 (r-> right) ;}} void travel_1 () {travel_1 (root); cout <endl;}/** ordinal traversal, non-recursive mode */void travel_2 (node * r) {if (r! = NULL) {stack <node *> s; while (r! = NULL |! S. empty () {while (r! = NULL) {s. push (r); r = r-> left;} if (! S. empty () {r = s. top (); s. pop (); cout <r-> key <''; r = r-> right ;}}} void travel_2 () {travel_2 (root ); cout <endl;}/** forward traversal, recursion */void travel_3 (node * r) {if (r! = NULL) {cout <r-> key <''; travel_3 (r-> left); travel_3 (r-> right) ;}} void travel_3 () {travel_3 (root); cout <endl;}/** pre-order traversal, non-recursive mode */void travel_4 (node * r) {if (r! = NULL) {stack <node *> s; while (r! = NULL |! S. empty () {while (r! = NULL) {cout <r-> key <''; s. push (r); r = r-> left;} if (! S. empty () {r = s. top (); s. pop (); r = r-> right ;}}} void travel_4 () {travel_4 (root); cout <endl ;}/ ** post-order method, recursion */void travel_5 (node * r) {if (r! = NULL) {travel_5 (r-> left); travel_5 (r-> right); cout <r-> key <'';}} void travel_5 () {travel_5 (root); cout <endl;}/** post-order mode, non-recursion */void travel_6 (node * r) {if (r = NULL) {return;} stack <node *> s; node * current_pointer; node * last_pointer; // record the pointer s of the previous loop. push (r); // first press the root node to stack while (! S. empty () {current_pointer = s. top (); // update the current pointer to the new stack top if (current_pointer-> left = NULL & current_pointer-> right = NULL) for each loop) | (last_pointer! = NULL & (last_pointer = current_pointer-> left | last_pointer = current_pointer-> right) {cout <current_pointer-> key <''; s. pop (); last_pointer = current_pointer;} else {if (current_pointer-> right! = NULL) {s. push (current_pointer-> right);} if (current_pointer-> left! = NULL) {s. push (current_pointer-> left) ;}}} void travel_6 () {travel_6 (root); cout <endl ;}};












Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.