--- Binary Tree recursion (non-recursion) Implement first-order, middle-order, and post-order traversal (with code), --- Binary Tree

Source: Internet
Author: User

--- Binary Tree recursion (non-recursion) Implement first-order, middle-order, and post-order traversal (with code), --- Binary Tree

Today, I said that I did not touch the code, but I still couldn't resist it. I learned how to learn data structures and algorithms. Let's talk about the first and then the next steps. I also wrote the code, A set of recursive methods are used to traverse binary trees, and two non-recursive methods are used to traverse Binary Trees,


From a simple start, because all operations on Binary Trees require traversal.


Those who have learned the data structure must understand the traversal sequence,

The first traversal is to first traverse the child tree, then the left child tree, and then the right child tree,

In the middle-order traversal, the left subtree is first, then the self, and then the right subtree

After the traversal, the left subtree is first, then the right subtree, and then




For example, this simple binary tree:

Sequential traversal: 1 2 4 5 3 6 7

Sequential traversal: 4 2 5 1 6 3 7

Post-order traversal: 4 5 2 6 7 3 1

The specific Traversal method is what we mentioned above.


Let's leave it blank. We use the code to implement it:

Let's talk about simple recursion:

Class Node // Tree Node, without the c ++ template, we only talk about the algorithm. The template is slowly {public: int data; Node * pLeft = NULL; node * pRight = NULL ;};

Node * pRoot; // a simple and crude method to initialize a tree. The focus is not on this. You can perform Node s1, Node s2, Node s3, Node s4, Node s5, and Node s6 on your own; node s7; s1.data = 1; s2.data = 2; s3.data = 3; s4.data = 4; s5.data = 5; s6.data = 6; s7.data = 7; pRoot = & s1; s1.pLeft = & s2; s1.pRight = & s3; s2.pLeft = & s4; s2.pRight = & s5; s3.pLeft = & s6; s3.pRight = & s7;

The following is the focus:

Void qiandigui (Node * pRoot) // recursive method. The binary tree {if (pRoot = nullptr) {return ;}cout <pRoot-> data <""; if (pRoot-> pLeft! = Nullptr) {qiandigui (pRoot-> pLeft);} if (pRoot-> pRight! = Nullptr) {qiandigui (pRoot-> pRight );}}

Void zhongdigui (Node * pRoot) <span style = "white-space: pre"> </span> <span style = "font-family: Arial, Helvetica, sans-serif; ">/// recursive method, traversing a binary tree in the middle order </span> {if (pRoot = nullptr) {return;} if (pRoot-> pLeft! = Nullptr) {zhongdigui (pRoot-> pLeft);} cout <pRoot-> data <""; if (pRoot-> pRight! = Nullptr) {zhongdigui (pRoot-> pRight );}}

Void houdigui (Node * pRoot) <span style = "white-space: pre"> </span> // recursive method that traverses Binary Trees in descending order {if (pRoot = nullptr) {return;} if (pRoot-> pLeft! = Nullptr) {houdigui (pRoot-> pLeft);} if (pRoot-> pRight! = Nullptr) {houdigui (pRoot-> pRight) ;}cout <pRoot-> data <"";}

The following describes non-recursive algorithms:

Note: unlike other blogs, non-recursive algorithms are used here. I have two sets of non-recursive algorithms, one set I wrote myself. It feels good. You can check it out, you can also give me some comments. Another one is very popular on the Internet.


Let's start with the online popularity:

Void stackxianpopulance (Node * pRoot) <span style = "white-space: pre"> </span> // non-recursive method, traverse the binary tree {stack <Node *> mystack; Node * pnow = pRoot; while (pnow! = Nullptr | false = mystack. empty () {while (pnow) {cout <pnow-> data <""; mystack. push (pnow); pnow = pnow-> pLeft;} pnow = mystack. top (); mystack. pop (); pnow = pnow-> pRight ;}}

Void stackzhongpopulance (Node * pRoot) <span style = "white-space: pre"> </span> // non-recursive method, traversing a binary tree in the middle order {stack <Node *> mystack; node * pnow = pRoot; while (pnow! = Nullptr | false = mystack. empty () {while (pnow) {mystack. push (pnow); pnow = pnow-> pLeft;} pnow = mystack. top (); mystack. pop (); cout <pnow-> data <""; pnow = pnow-> pRight ;}}

Because this post-ordered binary tree needs to find the right subtree after traversing the left subtree, a popular version on the Internet is very late today, and it is too lazy to implement it, because the blogger will have to take the test tomorrow. It is estimated that it will be another night after the test is completed,

So I will look for a copy on the Internet for you to see, in order to temporarily come to the top:

In non-recursive traversal of pre-order, middle-order, and post-order, it is the most troublesome to count post-order. It is not enough to keep the pointer to the node only in the stack, some additional information must be stored in the stack. There are many methods. Here is only one method. First, define the data structure of the stack Node typedef struct {Node * p; int rvisited;} SNode // Node is the Node Structure of the binary tree, rvisited = 1 indicates that the right node of the node to which p points has been accessed. LastOrderTraverse (BiTree bt) {// first, start from the root node and go down to the bottom left until the header is reached. each node in the path is put into the stack. P = bt; while (bt) {push (bt, 0); // push two messages to the stack. One is the node pointer, first, whether the right node has been accessed by bt = bt. lchild;} // then enter the loop body while (! Stack. empty () {// as long as the Stack is not empty sn = Stack. getTop (); // sn indicates the top node of the stack. // note that if any node N has a left child, after N is added to the stack, n's left child must also follow the stack (this is reflected in the second half of the algorithm), so when we get the top element of the stack, we can be sure that this element is either not left child, either the left child has been accessed, so we don't care about its left child. We only care about its right child. // If the right child has been accessed, or the element does not have the right child, it is defined by post-order traversal. At this time, you can view the node. If (! Sn. p. rchild | sn. rvisited) {p = pop (); visit (p) ;}else // if its right child exists and rvisited is 0, it indicates that it has not been moved to the right child before, so I processed the right child. {// At this time, we will start from its right child node and go down to the bottom left until it reaches the end, putting all the nodes on this path into the stack. // Of course, you must set rvisited of the node to 1 before going into the stack, because its right child's going into the stack means that its right child will be accessed before it (this is easy to understand, because we always retrieve elements from the top of the stack for visit ). It can be seen that when this element is at the top of the stack, the right child must have been visit, so you can set rvisited to 1 here. Sn. rvisited = 1; // to the bottom left to end, put all elements in the path into the stack p = sn. p. rchild; while (p! = 0) {push (p, 0); p = p. lchild;} // This cycle has ended. We don't have to worry about the nodes that just entered the stack. The nodes will be well cared for in the next cycle. }}
The code of the eldest brother above is as follows: ctrl + c, ctrl + v, and paste it. Ask that person. If you see it, forget it. Maybe you did, haha...


Next, I wrote this set by myself. I don't know if it is not suitable for everyone. Let's take a look. I feel that this change is much better than the previous version of populance, for example, you can change the pre-order to the middle order, and then change the pre-order to the back order.

Paste the Code:


Class StackNode <span style = "white-space: pre"> </span> // This Is The type installed in the stack, {public: bool flag = false; // The flag indicates whether it can be printed. In this case, Node * p = nullptr; StackNode (bool flag, Node * p): flag (flag ), p (p ){}};


Void xianstackmy (Node * pRoot) <span style = "white-space: pre"> </span> // non-Recursive Implementation. traverse the binary tree in sequence {stack <StackNode> mystack; if (pRoot = nullptr) {return;} mystack. push (StackNode (false, pRoot); while (false = mystack. empty () {StackNode now = mystack. top (); mystack. pop (); if (now. p! = Nullptr) {if (now. flag) // if it can be printed, it will be printed. The flag means {cout <now. p-> data <";} else {mystack. push (StackNode (false, now. p-> pRight); // press the right subtree to the bottom of the stack, mystack. push (StackNode (false, now. p-> pLeft); // press the left subtree to stack now. flag = true; // the current node is set to print mystack. push (now); // press the node stack that can be printed currently }}cout <endl ;}

Void zhonstackmy (Node * pRoot) <span style = "white-space: pre"> </span> // non-Recursive Implementation, traversing a binary tree in the middle order {stack <StackNode> mystack; if (pRoot = nullptr) {return;} mystack. push (StackNode (false, pRoot); while (false = mystack. empty () {StackNode now = mystack. top (); mystack. pop (); if (now. p = nullptr) {continue;} if (now. flag) // we have previously set up printable items. The items that can be printed here are printed directly. If they do not match, execute else {cout <now. p-> data <";} else {mystack. push (StackNode (false, now. p-> pRight); // first press the right subtree to the bottom of the stack now. flag = true; // the current node is set to print mystack. push (now); mystack. push (StackNode (false, now. p-> pLeft); // press the left subtree to the bottom of the stack }}cout <endl ;}


Void houstackmy (Node * pRoot) <span style = "white-space: pre"> </span> // non-Recursive Implementation, traverse the binary tree {stack <StackNode> mystack in the descending order; if (pRoot = nullptr) {return;} mystack. push (StackNode (false, pRoot); while (false = mystack. empty () {StackNode now = mystack. top (); mystack. pop (); if (now. p = nullptr) {continue;} if (now. flag) {cout <now. p-> data <";} else {now. flag = true; // set the current node to print the mystack. push (now); mystack. push (StackNode (false, now. p-> pRight); // press the right subtree of the stack, mystack. push (StackNode (false, now. p-> pLeft); // press the left subtree of the stack. }}cout <endl ;}

The above is the binary tree traversal method I wrote. If you have any questions, please kindly advise,


What I wrote should be the indirect conversion method for Recursive stack conversion,

The template is as follows:

Indirect conversion method:

This method uses the stack to save intermediate results. Generally, the result is obtained based on the stack changes of recursive functions during execution. The general process is as follows:

<1> Add the initial s0 to the stack


<2> while (Stack is not empty)
{
Stack rollback: grant the top element of the stack to s;
If (s is the result to be found ){


Return;


}


Else {
Locate s-related status s1;
Stack s1;
}
}




You see, this is probably the case with my template. Recursive parameters and logic are very important,

Recursive stack conversion, how to use the stack to simulate recursion, and the parameters are very important. Just understand these.


I will continue to study this question in a few days. I will share my findings with you,


I have to take the exam tomorrow. I have to brush my teeth today, and then go to bed. I hope you will forgive me for not speaking carefully.

Related Article

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.