二叉树的遍历:先序 中序 后序遍历的递归与非递归实现及层序遍历

二叉树的定义:一种基本的数据结构,是一种每个节点的儿子数目都不多于2的树

树节点的定义如下:

// 树(节点)定义
struct TreeNode 
{
	int		data; // 值
	TreeNode*	left; // 左节点
	TreeNode*	right;// 右节点
};

创建树(从上而下构建,我们以0表空节点)

结果如下图:

代码如下:

// 按照前序建立二叉树,这里我们建立下面的树
//			8
//		6		11
//	  4	  7			12
// 所以输入顺序是:864007001101200
void createTree(TreeNode*& t)
{	
	cout<<"请输入数据:"<<endl;
	int val = 0;
	cin>>val;

	// 0表结束
	if (0 == val)
	{
		t = NULL;
	}
	else 
	{
		t = new TreeNode();
		t->data = val;
		cout<<"开始建立:"<<val<<"的左节点:";
		createTree(t->left);
		cout<<"开始建立:"<<val<<"右节点:";
		createTree(t->right);
	}
}

前序遍历的递归法和非递归法:

结果如下图:

代码如下:

		前序遍历		/
// 递归法
void Pre_Recursive(TreeNode* pTree)
{	
	if (pTree != NULL)
	{
		cout<<pTree->data<<endl;	// 根节点
		Pre_Recursive(pTree->left);		// 左子
		Pre_Recursive(pTree->right);	// 右子
	}
}

// 非递归法
void Pre_No_Recursive(TreeNode* pTree)
{	
	TreeNode* pTemp = pTree;
	stack<TreeNode*> treeStack;

	
	while(pTemp || !treeStack.empty())
	{
		// pTemp有效时就访问,入栈,指向左子,一直这样
		while(pTemp != NULL)
		{
			// 访问
			cout<<pTemp->data<<endl;
			// 压入
			treeStack.push(pTemp);
			// 指向左子
			pTemp = pTemp->left;
		}

		// 栈非空时,回退一个节点,指向右子
		if (pTemp == NULL && !treeStack.empty())
		{
			pTemp = treeStack.top();
			// 指向右子
			pTemp = pTemp->right;
			// 弹出
			treeStack.pop();
		}
	}
}

中序遍历的递归法和非递归法:

结果如下图:

代码如下:

		中序遍历		/
// 递归法
void Mid_Recursive(TreeNode* pTree)
{	
	if (pTree != NULL)
	{
		Mid_Recursive(pTree->left);		// 左子
		cout<<pTree->data<<endl;		// 根节点
		Mid_Recursive(pTree->right);	// 右子
	}
}

// 非递归法
void Mid_No_Recursive(TreeNode* pTree)
{	
	TreeNode* pTemp = pTree;
	stack<TreeNode*> treeStack;


	while(pTemp || !treeStack.empty())
	{
		// pTemp有效时就入栈,指向左子,一直这样
		while(pTemp != NULL)
		{
			// 压入
			treeStack.push(pTemp);
			// 指向左子
			pTemp = pTemp->left;
		}

		if (pTemp == NULL && !treeStack.empty())
		{
			pTemp = treeStack.top();
			cout<<pTemp->data<<endl;
			// 指向右子
			pTemp = pTemp->right;
			// 弹出
			treeStack.pop();
		}
	}
}

后序遍历的递归法和非递归法:

结果如下图:

代码如下:

		后序遍历		/
// 递归法
void After_Recursive(TreeNode* pTree)
{	
	if (pTree != NULL)
	{
		After_Recursive(pTree->left);	// 左子
		After_Recursive(pTree->right);	// 右子
		cout<<pTree->data<<endl;		// 根节点
	}
}

// 非递归法
void After_No_Recursive(TreeNode* pTree)
{	
	TreeNode* pTemp = pTree;
	stack<TreeNode*> treeStack1;// 临时存储节点
	stack<TreeNode*> treeStack2;// 存储所有的节点,顺序:根节点,右子,左子,后面只需打印即可


	while(pTemp || !treeStack1.empty())
	{
		// pTemp有效时就入栈,指向左子,一直这样
		while(pTemp != NULL)
		{
			// 压入本节点
			treeStack1.push(pTemp);
			treeStack2.push(pTemp);
			
			// 指向右子
			pTemp = pTemp->right;
		}

		if(pTemp == NULL && !treeStack1.empty()) 
		{
			pTemp = treeStack1.top();
			pTemp = pTemp->left;
			treeStack1.pop();
		}
	}

	// 由于存储顺序是:根节点,右子,左子,这里只需逐个打印
	while(!treeStack2.empty())
	{
		pTemp = treeStack2.top();
		cout<<pTemp->data<<endl;
		treeStack2.pop();
	}
}

层序遍历的非递归法:

结果如下图:

代码如下:

// 层序遍历
void Level_Recursive(TreeNode* pTree)
{
	if (pTree == NULL)
	{
		return;
	}
	
	queue<TreeNode*> que;
	que.push(pTree);

	while(!que.empty())
	{
		// 取得队列头部元素,后把节点出队
		TreeNode* pTemp = que.front();
		que.pop();

		cout<<pTemp->data<<endl;

		// 压入左子,右子
		if (pTemp->left != NULL)
		{
			que.push(pTemp->left);
		}
		if (pTemp->right != NULL)
		{
			que.push(pTemp->right);
		}
	}
}

完整代码如下:

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

// 树(节点)定义
struct TreeNode 
{
	int			data;
	TreeNode*	left;
	TreeNode*	right;
};

// 按照前序建立二叉树,这里我们建立下面的树
//			8
//		6		11
//	  4	  7			12
// 所以输入顺序是:864007001101200
void createTree(TreeNode*& t)
{	
	cout<<"请输入数据:"<<endl;
	int val = 0;
	cin>>val;

	// 0表结束
	if (0 == val)
	{
		t = NULL;
	}
	else 
	{
		t = new TreeNode();
		t->data = val;
		cout<<"开始建立:"<<val<<"的左节点:";
		createTree(t->left);
		cout<<"开始建立:"<<val<<"右节点:";
		createTree(t->right);
	}
}

		前序遍历		/
// 递归法
void Pre_Recursive(TreeNode* pTree)
{	
	if (pTree != NULL)
	{
		cout<<pTree->data<<endl;	// 根节点
		Pre_Recursive(pTree->left);		// 左子
		Pre_Recursive(pTree->right);	// 右子
	}
}

// 非递归法
void Pre_No_Recursive(TreeNode* pTree)
{	
	TreeNode* pTemp = pTree;
	stack<TreeNode*> treeStack;

	
	while(pTemp || !treeStack.empty())
	{
		// pTemp有效时就访问,入栈,指向左子,一直这样
		while(pTemp != NULL)
		{
			// 访问
			cout<<pTemp->data<<endl;
			// 压入
			treeStack.push(pTemp);
			// 指向左子
			pTemp = pTemp->left;
		}

		// 栈非空时,回退一个节点,指向右子
		if (pTemp == NULL && !treeStack.empty())
		{
			pTemp = treeStack.top();
			// 指向右子
			pTemp = pTemp->right;
			// 弹出
			treeStack.pop();
		}
	}
}

		中序遍历		/
// 递归法
void Mid_Recursive(TreeNode* pTree)
{	
	if (pTree != NULL)
	{
		Mid_Recursive(pTree->left);		// 左子
		cout<<pTree->data<<endl;		// 根节点
		Mid_Recursive(pTree->right);	// 右子
	}
}

// 非递归法
void Mid_No_Recursive(TreeNode* pTree)
{	
	TreeNode* pTemp = pTree;
	stack<TreeNode*> treeStack;


	while(pTemp || !treeStack.empty())
	{
		// pTemp有效时就入栈,指向左子,一直这样
		while(pTemp != NULL)
		{
			// 压入
			treeStack.push(pTemp);
			// 指向左子
			pTemp = pTemp->left;
		}

		if (pTemp == NULL && !treeStack.empty())
		{
			pTemp = treeStack.top();
			cout<<pTemp->data<<endl;
			// 指向右子
			pTemp = pTemp->right;
			// 弹出
			treeStack.pop();
		}
	}
}

		后序遍历		/
// 递归法
void After_Recursive(TreeNode* pTree)
{	
	if (pTree != NULL)
	{
		After_Recursive(pTree->left);	// 左子
		After_Recursive(pTree->right);	// 右子
		cout<<pTree->data<<endl;		// 根节点
	}
}

// 非递归法
void After_No_Recursive(TreeNode* pTree)
{	
	TreeNode* pTemp = pTree;
	stack<TreeNode*> treeStack1;// 临时存储节点
	stack<TreeNode*> treeStack2;// 存储所有的节点,顺序:根节点,右子,左子,后面只需打印即可


	while(pTemp || !treeStack1.empty())
	{
		// pTemp有效时就入栈,指向左子,一直这样
		while(pTemp != NULL)
		{
			// 压入本节点
			treeStack1.push(pTemp);
			treeStack2.push(pTemp);
			
			// 指向右子
			pTemp = pTemp->right;
		}

		if(pTemp == NULL && !treeStack1.empty()) 
		{
			pTemp = treeStack1.top();
			pTemp = pTemp->left;
			treeStack1.pop();
		}
	}

	// 由于存储顺序是:根节点,右子,左子,这里只需逐个打印
	while(!treeStack2.empty())
	{
		pTemp = treeStack2.top();
		cout<<pTemp->data<<endl;
		treeStack2.pop();
	}
}

// 层序遍历
void Level_Recursive(TreeNode* pTree)
{
	if (pTree == NULL)
	{
		return;
	}
	
	queue<TreeNode*> que;
	que.push(pTree);

	while(!que.empty())
	{
		// 取得队列头部元素,后把节点出队
		TreeNode* pTemp = que.front();
		que.pop();

		cout<<pTemp->data<<endl;

		// 压入左子,右子
		if (pTemp->left != NULL)
		{
			que.push(pTemp->left);
		}
		if (pTemp->right != NULL)
		{
			que.push(pTemp->right);
		}
	}
}

int main()
{
	TreeNode* pTree = NULL;
	createTree(pTree);

	// 前序-递归法
	cout<<"\n递归法前序遍历树"<<endl;
	Pre_Recursive(pTree);

	// 前序-非递归法
	cout<<"\n非递归法前序遍历树"<<endl;
	Pre_No_Recursive(pTree);

	// 中序-递归法
	cout<<"\n递归法中序遍历树"<<endl;
	Mid_Recursive(pTree);

	// 中序-非递归法
	cout<<"\n非递归法中序遍历树"<<endl;
	Mid_No_Recursive(pTree);

	// 后序-递归法
	cout<<"\n递归法后序遍历树"<<endl;
	After_Recursive(pTree);

	// 后序-非递归法
	cout<<"\n非递归法后序遍历树"<<endl;
	After_No_Recursive(pTree);

	// 层序遍历-非递归法
	cout<<"\n非递归法层序遍历树"<<endl;
	Level_Recursive(pTree);

	system("pause");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值