Non-recursive traversal of binary tree
Binary tree is a very important data structure, many other data structures are based on the binary Tree Foundation evolved. For binary trees, there are three kinds of traversal methods, such as sequence, middle order and sequential sequence. Since the definition of a tree is itself a recursive definition, it is not only easy to understand the three traversal of the tree and the code is concise. And for the tree traversal if the method is not recursive, it is necessary to use the stack to simulate implementation. In three kinds of traversal, the non recursive algorithm of sequence and sequence traversal is easy to realize, and it is relatively difficult to realize the recursive sequential traversal.
I. Pre-sequence traversal
The forward traversal is accessed in the order of "root node-left child-right child".
1. Recursive implementation
Copy Code code as follows:
void PreOrder1 (Bintree *root)//recursive forward traversal
{
if (root!=null)
{
cout<<root->data<< "";
PreOrder1 (Root->lchild);
PreOrder1 (Root->rchild);
}
}
2. Non-recursive implementation
According to the order of the previous traversal access, the root node is first accessed, and then the left and right children are accessed separately. That is, for any node, it can be seen as a root node, so you can directly access, after the visit, if the left child is not empty, according to the same rules to access its left subtree, access to its left subtree, and then access its right subtree. The process is therefore as follows:
For any node P:
1) Accessing the node p and putting the node p into the stack;
2) To determine if the left child of the node P is empty, if empty, then take the stack top node and carry out stack operation, and the top node of the stack of the right child into the current node p, loop to 1; if not empty, then P's left child is placed as the current node p;
3) The traversal ends until p is null and the stack is empty.
Copy Code code as follows:
void PreOrder2 (Bintree *root)//non-recursive pre-sequence traversal
{
Stack<bintree*> s;
Bintree *p=root;
while (p!=null| |! S.empty ())
{
while (P!=null)
{
cout<<p->data<< "";
S.push (P);
p=p->lchild;
}
if (!s.empty ())
{
P=s.top ();
S.pop ();
p=p->rchild;
}
}
}
two. In-sequence traversal
The sequence traversal is accessed in the order of "left child-root node-right child".
1. Recursive implementation
Copy Code code as follows:
void InOrder1 (Bintree *root)//recursive sequence traversal
{
if (root!=null)
{
InOrder1 (Root->lchild);
cout<<root->data<< "";
InOrder1 (Root->rchild);
}
}
2. Non-recursive implementation
According to the order of the sequence traversal, for any node, priority access to the left child, and the left child node can be seen as a node, and then continue to visit its left child node, until you encounter the left child node is empty node to access, and then follow the same rules to access its right subtree. The process is therefore as follows:
For any node p,
1) If the left child is not empty, the P is placed on the stack and the left child of P is placed as the current p, and then the current node p is treated the same;
2) If the left child is empty, take the top element of the stack and carry out the stack operation, access the top node of the stack, and then place the current p as the top node of the stack right child;
3) Traversal ends until p is null and the stack is empty
Copy Code code as follows:
void InOrder2 (Bintree *root)//non-recursive sequence traversal
{
Stack<bintree*> s;
Bintree *p=root;
while (p!=null| |! S.empty ())
{
while (P!=null)
{
S.push (P);
p=p->lchild;
}
if (!s.empty ())
{
P=s.top ();
cout<<p->data<< "";
S.pop ();
p=p->rchild;
}
}
}
three. Subsequent traversal
The sequential traversal is accessed in the order of "left child-right child-root node".
1. Recursive implementation
Copy Code code as follows:
void PostOrder1 (Bintree *root)//recursive sequence traversal
{
if (root!=null)
{
PostOrder1 (Root->lchild);
PostOrder1 (Root->rchild);
cout<<root->data<< "";
}
}
2. Non-recursive implementation
The recursive implementation of subsequent traversal is the most difficult one of the three kinds of traversal methods. Because in the subsequent traversal, to ensure that both the left and right children have been visited and left children in front of the right child access to access to root node, which for the control of the process has brought difficulties. Here are two ways of thinking.
The first way: for any node p, put it on the stack and search down the left subtree until you find a node with no left child, which appears at the top of the stack, but cannot be pushed out of the stack and accessed at this time, so the right child is also accessed. So next, follow the same rule on the right subtree, and when the right child is accessed, the node appears on the top of the stack, which can then be stack and accessed. This guarantees the correct access order. As you can see, in this process, each node appears at the top of the stack two times, only to access it the second time it appears at the top of the stack. Therefore, it is necessary to set a variable to identify whether the node is the first occurrence at the top of the stack.
Copy Code code as follows:
void PostOrder2 (Bintree *root)//non-recursive sequence traversal
{
Stack<btnode*> s;
Bintree *p=root;
Btnode *temp;
while (p!=null| |! S.empty ())
{
while (p!=null)//Zuozi down the search until a node with no left subtree appears
{
Btnode *btn= (Btnode *) malloc (sizeof (Btnode));
btn->btnode=p;
btn->isfirst=true;
S.push (BTN);
p=p->lchild;
}
if (!s.empty ())
{
Temp=s.top ();
S.pop ();
if (temp->isfirst==true)//representation is the first time to appear on the top of the stack
{
temp->isfirst=false;
S.push (temp);
p=temp->btnode->rchild;
}
else//second appearance on top of stack
{
cout<<temp->btnode->data<< "";
P=null;
}
}
}
}
The second way of thinking:To ensure that the root node is accessible to the left child and the right child, it is first put into the stack for any node p. If p does not exist for the left child and the right child, you can access it directly, or there is a left child or right child in P, but both the left and right children have been visited, and the node can be accessed directly. In either case, the right child of P and the left child are sequentially placed in the stack, which ensures that every time the top element is taken, the left child is visited in front of the right child, and the left child and the right child are accessed before the root node.
Copy Code code as follows:
void PostOrder3 (Bintree *root)//non-recursive sequence traversal
{
Stack<bintree*> s;
Bintree *cur; Current node
Bintree *pre=null; node of previous visit
S.push (root);
while (!s.empty ())
{
Cur=s.top ();
if ((cur->lchild==null&&cur->rchild==null) | |
(pre!=null&& (pre==cur->lchild| | Pre==cur->rchild)))
{
cout<<cur->data<< ""; If the current node has no children or the child nodes have been visited
S.pop ();
Pre=cur;
}
Else
{
if (cur->rchild!=null)
S.push (Cur->rchild);
if (cur->lchild!=null)
S.push (Cur->lchild);
}
}
}
Four. Complete code for the entire program
Copy Code code as follows:
#include <iostream>
#include <string.h>
#include <stack>
using namespace Std;
typedef struct NODE
{
char data;
struct node *lchild,*rchild;
}bintree;
typedef struct NODE1
{
Bintree *btnode;
BOOL Isfirst;
}btnode;
void Creatbintree (char *s,bintree *&root)//Create a two-fork tree, S is a string in the form of a (B,c (d,e))
{
int i;
BOOL Isright=false;
stack<bintree*> S1;//Storage node
stack<char> s2;//Storage separator
Bintree *p,*temp;
root->data=s[0];
root->lchild=null;
root->rchild=null;
S1.push (root);
I=1;
while (I<strlen (s))
{
if (s[i]== ' (')
{
S2.push (s[i]);
Isright=false;
}
Else if (s[i]== ', ')
{
isright=true;
}
Else if (s[i]== ') ')
{
S1.pop ();
S2.pop ();
}
Else if (Isalpha (s[i))
{
p= (Bintree *) malloc (sizeof (Bintree));
p->data=s[i];
p->lchild=null;
p->rchild=null;
Temp=s1.top ();
if (isright==true)
{
temp->rchild=p;
cout<<temp->data<< "The right child is" <<s[i]<<endl;
}
Else
{
Temp->lchild=p;
cout<<temp->data<< "The left child is" <<s[i]<<endl;
}
if (s[i+1]== ' (')
S1.push (P);
}
i++;
}
}
void display (Bintree *root)//Display tree structure
{
if (root!=null)
{
cout<<root->data;
if (root->lchild!=null)
{
cout<< ' (';
Display (root->lchild);
}
if (root->rchild!=null)
{
cout<< ', ';
Display (root->rchild);
cout<< ') ';
}
}
}
void PreOrder1 (Bintree *root)//recursive forward traversal
{
if (root!=null)
{
cout<<root->data<< "";
PreOrder1 (Root->lchild);
PreOrder1 (Root->rchild);
}
}
void InOrder1 (Bintree *root)//recursive sequence traversal
{
if (root!=null)
{
InOrder1 (Root->lchild);
cout<<root->data<< "";
InOrder1 (Root->rchild);
}
}
void PostOrder1 (Bintree *root)//recursive sequence traversal
{
if (root!=null)
{
PostOrder1 (Root->lchild);
PostOrder1 (Root->rchild);
cout<<root->data<< "";
}
}
void PreOrder2 (Bintree *root)//non-recursive pre-sequence traversal
{
Stack<bintree*> s;
Bintree *p=root;
while (p!=null| |! S.empty ())
{
while (P!=null)
{
cout<<p->data<< "";
S.push (P);
p=p->lchild;
}
if (!s.empty ())
{
P=s.top ();
S.pop ();
p=p->rchild;
}
}
}
void InOrder2 (Bintree *root)//non-recursive sequence traversal
{
Stack<bintree*> s;
Bintree *p=root;
while (p!=null| |! S.empty ())
{
while (P!=null)
{
S.push (P);
p=p->lchild;
}
if (!s.empty ())
{
P=s.top ();
cout<<p->data<< "";
S.pop ();
p=p->rchild;
}
}
}
Void PostOrder2 (Bintree *root)//non-recursive sequence traversal
{
stack<btnode*> s;
Bintree *p=root;
Btnode *temp;
while (p!=null| |! S.empty ())
{
while (p!=null)///down Zuozi until a node with no left subtree appears
{
Btnode *btn= (Btnode *) malloc (sizeof);
btn->btnode=p;
btn->isfirst=true;
S.push (BTN);
p=p->lchild;
}
if (!s.empty ())
{
Temp=s.top ();
S.pop ();
if (temp->isfirst==true)//Represents the first occurrence on the top of the stack
{
Temp->isfirst=false;
S.push (temp);
p=temp->btnode->rchild;
}
Else//second appears on the top of the stack
{
cout<<temp->btnode->data<< "";
P=null;
}
}
}
}
void PostOrder3 (Bintree *root)//non-recursive sequence traversal
{
Stack<bintree*> s;
Bintree *cur; Current node
Bintree *pre=null; node of previous visit
S.push (root);
while (!s.empty ())
{
Cur=s.top ();
if ((cur->lchild==null&&cur->rchild==null) | |
(pre!=null&& (pre==cur->lchild| | Pre==cur->rchild)))
{
cout<<cur->data<< ""; If the current node has no children or the child nodes have been visited
S.pop ();
Pre=cur;
}
Else
{
if (cur->rchild!=null)
S.push (Cur->rchild);
if (cur->lchild!=null)
S.push (Cur->lchild);
}
}
}
int main (int argc, char *argv[])
{
Char s[100];
while (scanf ("%s", s) ==1)
{
Bintree *root= (Bintree *) malloc (sizeof (bintree));
Creatbintree (S,root);
display (root);
cout<<endl;
PreOrder2 (root);
cout<<endl;
InOrder2 (root);
cout<<endl;
PostOrder2 (root);
cout<<endl;
PostOrder3 (root);
cout<<endl;
}
return 0;
}