Review of data structure -- three traversal methods of binary tree

Posted by szcieder on Sun, 16 Jan 2022 04:40:19 +0100

Review of data structure -- traversal of binary tree

stl of c + + is used here. Remember to add header files
The language description may be confusing and the time is limited. It is mainly used for self review. The code problem should not be big

Establishment of binary tree structure

typedef struct BiTNode
{
	char data;
	struct BiTNode* lchild;
	struct BiTNode* rchild;
}BiTNode,*BiTree;

1. Preorder traversal (recursion)

void PreOrderTraverse(BiTree T)
{
	if(T)
	{
		cout<<T->data;
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}

}

2. Preorder traversal (non recursive)

void PreOrder(BiTree T)
{
	stack<BiTNode*> s;
	BiTNode *p=T;
	while(p || !s.empty()) 
	{
		if(p)
		{
			cout<<p->data;
			s.push(p);
			p=p->lchild;
		}
		else
		{
			p=s.top();
			s.pop();
			p=p->rchild;
		}
	}
}

Let's talk about the non recursive idea first:
Preorder traversal is
(1) Access root node
(2) Sequential access to left subtree
(3) Sequential access right subtree
Non recursive words will use a stack. The function of the stack is to store the experienced nodes, so that we can selectively return to the last node we need to return
The basic process is as follows;
(1) Enter the stack along the left child in turn until the left child is empty
(2) The top element of the stack goes out of the stack and returns to the root node of the previous layer
(3) Access the right child. If it is empty, repeat (2), otherwise repeat (1) (2)

2. Middle order traversal (recursion)

void InOrderTraverse(BiTree T)
{
	if(T)
	{
		InOrderTraverse(T->lchild);
		cout<<T->data;
		InOrderTraverse(T->rchild);
	}
}

4. Medium order traversal (non recursive)

void InOrder(BiTree T)
{
	stack<BiTNode*> s;
	BiTNode *p=T;
	while(p || !s.empty())
	{
		if(p)
		{
			s.push(p);
			p=p->lchild;
		}
		else
		{
			p=s.top();
			s.pop();
			cout<<p->data;
			p=p->rchild;
		}
	}
}

Let's talk about the idea of medium order non recursion:
Middle order traversal is
(1) Middle order traversal to access the left subtree
(2) Access root node
(3) Middle order traversal access right subtree
Non recursive words will use a stack. The function of the stack is to store the experienced nodes, so that we can selectively return to the last node we need to return.
The idea here is actually very similar to preorder traversal
The basic process is as follows;
(1) Enter the stack one by one along the left child and know that the left child is empty. At this time, the leaf found should be output
(2) The top element of the stack is out of the stack and accessed. If the right child is empty, continue to execute.
(3) If the right child is not empty, then execute operation (1)

5. Post order traversal (recursion)

void PostOrderTraverse(BiTree T)
{
	if(T)
	{
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		cout<<T->data;
	}
}

6. Post order traversal (non recursive)

void PostOrder(BiTree T)
{
	stack<BiTNode*> s;
	BiTNode *p=T;
	BiTNode *r=NULL;//Auxiliary pointer
	while(p || !s.empty())
	{
		if(p)
		{
			s.push(p);
			p=p->lchild;
		}
		else
		{
			p=s.top();
			if(p->rchild && p->rchild!=r)
			{
				p=p->rchild;
				s.push(p);
				p=p->lchild;
			}
			else
			{
				p=s.top();
				s.pop();
				cout<<p->data;
				r=p;
				p=NULL;
			}
		}
	} 
}

Post order non recursive idea:
An auxiliary pointer r is required
Post order traversal is:
(1) Post order traversal to access the left subtree
(2) Post order traversal access right subtree
(3) Access root node
The same will use the stack, which is a little more complex than the previous two
(1) Go along the left child and enter the stack in turn until the left child is empty
(2) Read the top element of the stack (if the right child has not accessed it and is not empty), then go to the right subtree for execution
Otherwise, it goes out of the stack and accesses the top element of the stack to return to the previous layer
Repeat (1) (2)

Code summary

#include <iostream>
#include <stack>
using namespace std;

typedef struct BiTNode
{
	char data;
	struct BiTNode* lchild;
	struct BiTNode* rchild;
}BiTNode,*BiTree;


void CreateBiTree(BiTree &T)
{
	char ch;
	cin>>ch;
	if(ch=='#')
		T=NULL;
	else
	{
		T=new BiTNode;
		T->data=ch;
		CreateBiTree(T->lchild);
		CreateBiTree(T->rchild);
	}
}

void InOrderTraverse(BiTree T)
{
	if(T)
	{
		InOrderTraverse(T->lchild);
		cout<<T->data;
		InOrderTraverse(T->rchild);
	}
}

void InOrder(BiTree T)
{
	stack<BiTNode*> s;
	BiTNode *p=T;
	while(p || !s.empty())
	{
		if(p)
		{
			s.push(p);
			p=p->lchild;
		}
		else
		{
			p=s.top();
			s.pop();
			cout<<p->data;
			p=p->rchild;
		}

	}
	
}
void PreOrderTraverse(BiTree T)
{
	if(T)
	{
		cout<<T->data;
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}

}

void PreOrder(BiTree T)
{
	stack<BiTNode*> s;
	BiTNode *p=T;
	while(p || !s.empty()) 
	{
		if(p)
		{
			cout<<p->data;
			s.push(p);
			p=p->lchild;
		}
		else
		{
			p=s.top();
			s.pop();
			p=p->rchild;
		}
	}
}

void PostOrderTraverse(BiTree T)
{
	if(T)
	{
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		cout<<T->data;
	}
}

void PostOrder(BiTree T)
{
	stack<BiTNode*> s;
	BiTNode *p=T;
	BiTNode *r=NULL;//Auxiliary pointer
	while(p || !s.empty())
	{
		if(p)
		{
			s.push(p);
			p=p->lchild;
		}
		else
		{
			p=s.top();
			if(p->rchild && p->rchild!=r)
			{
				p=p->rchild;
				s.push(p);
				p=p->lchild;
			}
			else
			{
				p=s.top();
				s.pop();
				cout<<p->data;
				r=p;
				p=NULL;
			}
		}
	} 
}

int main()
{
	BiTree T=new BiTNode;
	CreateBiTree(T);
	PreOrderTraverse(T);
	cout<<endl;
	PreOrder(T);
	cout<<endl;
	InOrderTraverse(T);
	cout<<endl;
	InOrder(T);
	cout<<endl;
	PostOrderTraverse(T);
	cout<<endl;
	PostOrder(T);
	return 0;
}
//test data
//-*a##b##c##

Topics: data structure Binary tree