Binary tree front, middle and back layer traversal (recursive/non-recursive) (easy to understand (*^ー^))

Binary tree traversal

1 preorder traversal

1.1 Recursion

Preorder Traversal (Preorder Traversal), namelyRoot or soorder to traverse the tree. The recursive code is as follows:

void preorder(Btree T)//递归先序遍历
{
    
    
	if(T)	//判断结点是否为空
	{
    
    
		visit(T);   //访问根结点
		preorder(T->lchild);	//递归遍历左子树
		preorder(T->rchild);	//递归遍历右子树
	}
}

1.2 Non-recursive

For non-recursive pre-order traversal, the stack is used to assist. The non-recursive code is as follows:

void preorder2(BiTree T){
    
    //非递归先序遍历
    InitStack(S);	//初始化栈S
    BiTree p = T;	//p作为遍历指针
    	while(p || !isEmpty(S)){
    
    	//栈不空或p非空就继续循环
            if(p){
    
    	//一路向左	
                visit(p);	//访问当前结点
                Push(S, p);	//将当期那结点入栈
                p = p->lchild;	//左孩子非空,就一直向左走
            }
            else{
    
    
                Pop(S, p);	//栈顶元素出栈
                p = p->rchild;	//向右子树走,p赋值为当前结点的右孩子
            }      
        }	
}

2 Inorder traversal

2.1 Recursion

Inorder Traversal (Inorder Traversal), namelyleft root rightTraversing the tree in order, the recursive code is as follows:

void inorder(BiTree T){
    
    	//递归中序遍历
	if(T){
    
    
		inorder(T->lchild);
		visit(T);
		inorder(T->lchild);
	}
}

2.2 Non-recursive

For non-recursive in-order traversal, the stack is used to assist. The non-recursive code is as follows:

void inorder2(BiTree T){
    
    	//非递归中序遍历
	InitStack(S);
	BiTree p = T;
	while(p || !IsEmpty(S)){
    
    
		if(p){
    
    
			Push(S, p);
			p = p->lchild;	//左
		}
		else{
    
    
			visit(p);	//根
			Pop(S, p);
			p = p->rchild;	//右
		}
	}
}

3 post-order traversal

3.1 Recursion

Postorder Traversal (Postorder Traversal), namelyleft and right rootsTraversing the tree in order, the recursive code is as follows:

void postorder(BiTree T){
    
    
	if(T){
    
    
		postorder(T->lchild);
		postorder(T->rchild);
		visit(T);
	}
}

3.2 Non-recursive

For non-recursive post-order traversal, the stack is used to assist.

​ It should be noted that there is a difference between the post-order non-recursive traversal algorithm and the pre-order in-order non-recursive traversal algorithm. When the post-order non-recursive algorithm is at a visitnode, it needs to ensureBoth the left child and the right child have been visited, and the left child needs to be visited before the right child (left and right root)

So when visita node is available, there are the following two situations:

  1. The left and right children of the node are empty
  2. The node has no right child, and the left child has been visited or the left and right children exist and both have been visited

For judging whether a node has been visited, we can define a pointer rto assist.

The non-recursive code is as follows:

void postorder2(BiTree T){
    
    	//非递归后序遍历
    InitStack(S);
    BiTNode *p = T; 	//注:写成BiTree p = T;也可
    BiTNode *r = NULL;		//注:写成BiTree r = NULL;也可
    while(p || !IsEmpty(S)){
    
    
        if(p){
    
    
            Push(S, p);
            p = p->lchild;	//左
        }
        else{
    
    
            GetTop(S, p);	//查看栈顶元素
            if(p->rchild && p->rchild != r){
    
    	//如果右孩子存在且没被访问过
                p = p->rchild;	//右
            }
            else{
    
    
                visit(p);	//根
                Pop(S, p);
                r = p;	//记录刚刚访问过的结点
                p = NULL;	//结点访问完,p置空以便继续回溯到其父节点进行后序遍历
            }
        }
    }
}

4 level order traversal

Level Order Traversal, namelyFrom top to bottom, from left to right, layer by layerto visit the node:

Figure 1 Level order traversal of binary tree

For the level-order traversal of the binary tree, queues are used to assist. code show as below:

void levelorder(BiTree T){
    
    
    InitQueue(Q);	//初始化辅助队列
    BiTree p;
    EnQueue(Q, T);	//根结点入队
    while(!IsEmpty(Q)){
    
    	//队列不为空则循环
        DeQueue(Q, p);	//队头结点出队
        visit(p);	//访问出队的结点
        if(p->lchild != NULL)	//出队结点的左孩子非空
            EnQueue(Q, p->lchild);	//左孩子入队
        if(p->rchild != NULL)	//出队结点的右孩子非空
            EnQueue(Q, p->rchild);	//右孩子入队
    }
}

5 Complete and runnable code (C++) for front, middle and back sequences

#include <iostream>
#include <queue>//引入队列头文件
using namespace std;

typedef struct Bnode	/*定义二叉树存储结构*/
{
    
     char data;
	struct Bnode *lchild,*rchild;
}Bnode,*Btree;

void Createtree(Btree &T)	/*创建二叉树函数*/
{
    
    
	//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
	char ch;
	cin >> ch;
	if(ch=='#')
		T=NULL;			//递归结束,建空树
	else{
    
    
		T=new Bnode;
		T->data=ch;					//生成根结点
		Createtree(T->lchild);	//递归创建左子树
		Createtree(T->rchild);	//递归创建右子树
	}
}

void preorder(Btree T)//先序遍历
{
    
    
	if(T)
	{
    
    
		cout<<T->data<<"  ";
		preorder(T->lchild);
		preorder(T->rchild);
	}
}

void inorder(Btree T)//中序遍历
{
    
    
	if(T)
	{
    
    
		inorder(T->lchild);
		cout<<T->data<<"  ";
		inorder(T->rchild);
	}
}

void posorder(Btree T)//后序遍历
{
    
    
	if(T)
	{
    
    
		posorder(T->lchild);
		posorder(T->rchild);
		cout<<T->data<<"  ";
	}
}

bool Leveltraverse(Btree T)
{
    
    
	Btree p;
	if(!T)
		return false;
	queue<Btree>Q; //创建一个普通队列(先进先出),里面存放指针类型
	Q.push(T); //根指针入队
	while(!Q.empty()) //如果队列不空
	{
    
    
		p=Q.front();//取出队头元素作为当前扩展结点livenode
		Q.pop(); //队头元素出队
		cout<<p->data<<"  ";
		if(p->lchild)
			Q.push(p->lchild); //左孩子指针入队
		if(p->rchild)
			Q.push(p->rchild); //右孩子指针入队
	}
	return true;
}

int main()
{
    
    
	Btree mytree;
	cout<<"按先序次序输入二叉树中结点的值(孩子为空时输入#),创建一棵二叉树"<<endl;
	Createtree(mytree);//创建二叉树
	cout<<endl;
	cout<<"二叉树的先序遍历结果:"<<endl;
	preorder(mytree);//先序遍历二叉树
	cout<<endl;
	cout<<"二叉树的中序遍历结果:"<<endl;
	inorder(mytree);//中序遍历二叉树
	cout<<endl;
	cout<<"二叉树的后序遍历结果:"<<endl;
	posorder(mytree);//后序遍历二叉树
	cout<<endl;
	cout<<"二叉树的层次遍历结果:"<<endl;
	Leveltraverse(mytree);//层次遍历二叉树
	return 0;
}

Enter description and example

This code includes creating a binary tree, pre-order traversal, in-order traversal, post-order traversal, and level traversal. The input sample should be a string, where each character represents the value of a node, input in the order of the preorder traversal. When the input character is "#", it means that the node is empty.

For example, for a binary tree like this:

    A
   / \
  B   C
 / \   \
D   E   F

The input sample should be: ABD##E##C#F##. Among them, Ais the root node, isB the left child node of , is the left child node of , means the left child node of is empty, the next means the right child node of is empty, and so on.ADB#D#D

operation result

Figure 2 Code running results

Guess you like

Origin blog.csdn.net/m0_56494923/article/details/130112784