二叉树的遍历

二叉树

二叉树是比较常用的数据结构之一,二叉树的遍历则有前序遍历,中序遍历、后序遍历以及层序遍历四种方法。前三种的遍历方法是根据树根被访问的顺序而命名的。
二叉树
我们把二叉树的左、中、右节点分别用L、V和R来表示,那么按照访问次序其实可以有六种访问顺序,分别为LVR、LRV、RVL、RLV、VLR和VRL。在这个基础上,我们规定左子树的访问必须在右子树之前,也就有了前序、中序以及后序遍历:VLR、LVR、LRV。

二叉树的定义

首先定义二叉树的定义:

using Position = struct Node*;
using BinTree = Position;
struct Node
{
	DataType data;
	BinTree left;
	BinTree right;
}

二叉树的遍历

前序遍历

前序遍历的过程为:
①访问根节点;
②前序访问其左子树;
③前序访问其右子树。
其实现可以用递归和非递归两种方式来实现,下面分别介绍两种实现方式。

递归方式
void preOrderTravel(BinTree BT)
{
	if(BT != nullptr)
	{
		cout<<BT->data<<endl;
		preOrderTravel(BT->left);
		preOrderTravel(BT->right);
	}
}
非递归方式
void preOrderTravel(BinTree BT)
{
	BinTree t;
	stack<BinTree> s;
	t = BT;
	while(t || !s.empty())
	{
		if(t)
		{
			cout<<t->data;
			s.push(t)
			t = t->left;
		}
		else if(!s.empty())
		{
			t = s.top();
			s.pop();
			t = t->right;
		}
	}
}

从非递归的遍历方式可以看出,当以前序的方式遍历时,每遇到一个节点,首先输出它的值,然后把它入栈,最后令该节点等于该节点的左子树。

中序遍历

递归方式
void inOrderTravel(BinTree BT)
{
	if(BT)
	{
		inOrderTravel(BT->left);
		cout<<BT->data;
		inOrderTravel(BT->right);
	}
}

可以看出来,递归方式的中序遍历和前序遍历的差别在于输出数据的行数变化,前序是先输出在递归遍历左子树,而中序是先递归处理左子树再输出。

非递归方式
void inOrderTravel(BinTree BT)
{
	stack<BinTree> s;
	while(BT || !s.empty())
	{
		if(BT)
		{
			s.push(BT);
			BT = BT->left;
		}
		else if(!s.empty())
		{
			BT = s.top();
			s.pop();
			cout<<BT->data<<endl;
			BT = BT->right;
		}
	}
}

这里也可以看出来,非递归的中序遍历方式和前序遍历的区别也是输出位置的不同;

后序遍历

事实上,后序遍历的递归和非递归方式也是只是输出的位置不同而已,这里给出代码

递归方式
void postOrderTravel(BinTree BT)
{
	if(BT)
	{
		postOrderTravel(BT->left);
		postOrderTravel(BT->right);
		cout<<BT->data<<endl;
	}
}

非递归方式
void postOrderTravel(BinTree BT)
{
	stack<BinTree> s;
	while( BT || !s.empty())
	{
		if(BT)
		{
			s.push(BT);
			BT = BT->left;
		}
		else if(!s.empty())
		{
			BT = s.top();
			s.pop();
			if(BT->right)
			{
				s.push(BT);
				BT = BT->right;
			}
			cout<<BT->data<<endl;
		}		
	}
}

层序遍历

最后是层序遍历,层序遍历的特点是每次遍历节点时,都把节点的左右子树压入队列中,从而达到自上而下遍历整棵树的目的。

void levelTravel(BinTree BT)
{
	if(!BT)return;
	queue<BinTree> q;
	BinTree T;
	q.push(BT);
	while(!q.empty())
	{
		T = q.front();
		q.pop();
		cout<<T->data<<endl;
		if(T->left)
			q.push(T->left);
		if(T->right)
			q.push(T->right);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值