数据结构 二叉树的遍历 学习笔记

首先  我们先来了解一下二叉树遍历的一些特性

二叉树的遍历分为前序遍历 ;中序遍历;后序遍历 ;

其中

前序遍历的顺序是  根  左 右

中序遍历的顺序是  左  根 右

后序遍历的顺序是  左  右 根 

相关图形如下  方便理解

 

 

关于二叉树非递归形式的遍历

下面  我们要对这样一个二叉树进行定义并且遍历

首先  我们先定义二叉树的结构体

struct BinaryTree
{
	int id;
	BinaryTree* Left;
	BinaryTree* Right;

};

 然后我们在主函数中创建一个这样的二叉树

//根
	BinaryTree* Boot = new BinaryTree;
	Boot->id = 1;
	//根的左
	Boot->Left = new BinaryTree;
	Boot->Left->id = 2;
	//根的左的左
	Boot->Left->Left = new BinaryTree;
	Boot->Left->Left->id = 4;
	Boot->Left->Left->Left = NULL;
	Boot->Left->Left->Right = NULL;
	//左的右
	Boot->Left->Right = new BinaryTree;
	Boot->Left->Right->id = 5;
	Boot->Left->Right->Left = NULL;
	Boot->Left->Right->Right = NULL;

	//根的右
	Boot->Right = new BinaryTree;
	Boot->Right->id = 3;
	//右的左
	Boot->Right->Left = new BinaryTree;
	Boot->Right->Left->id = 6;
	Boot->Right->Left->Left = NULL;
	Boot->Right->Left->Right = NULL;
	//右的右
	Boot->Right->Right = new BinaryTree;
	Boot->Right->Right->id = 7;
	Boot->Right->Right->Left = NULL;
	Boot->Right->Right->Right = NULL;

之后 我们开始进行对二叉树的遍历方法的编写

前序遍历:

这里用到了栈作为遍历方法的工具

所以我们引入头文件

#include<stack>

//前序遍历
void qianxubianli(BinaryTree*pRoot)
{
	//判断当前树是否为空
	if (NULL == pRoot)
		return;
	//定义一个栈用作工具
	stack<BinaryTree*>st;
	
	while (1)
	{
		//
		while (pRoot)
		{
			//打印当前节点并入栈
			cout << pRoot->id << " ";
			
			st.push(pRoot);  
			//向左走
				pRoot = pRoot->Left;
			
		}
		//左为空  判断当前栈是否为空   为空则遍历结束
		if (st.empty() == true)
		{
			cout << endl;
			return;
		}

		pRoot = st.top();
		//出栈
		st.pop();
		//向右走
		pRoot = pRoot->Right;
				
				
			
	
		
	}
	
	
	
}

中序遍历:

和前序遍历区别不大  只是打印的位置不同

//中序遍历
void zhongxubianli(BinaryTree* pRoot)
{
	if (NULL == pRoot)
		return;
	stack<BinaryTree*>st;

	while (1)
	{
		
		while (pRoot)
		{
			
			st.push(pRoot);

			pRoot = pRoot->Left;

		}
		
		if (st.empty() == true)
		{
			cout << endl;
			return;
		}
		
		pRoot = st.top();
		st.pop();
		
		cout << pRoot->id << " ";
		pRoot = pRoot->Right;
		
		
		
		





	}
	


}

后序遍历:

相对较复杂

前面的while(pRoot)大体相同

在处理出栈时有所不同而且需要设置一个标记来作为出栈的判断条件所使用的工具之一

BinaryTree* pMark = NULL;

pMark的作用主要是用来判断当前节点的右是否被处理过

pMark的作用是用来记录上一个被处理的节点

所以在出栈时  我们 对pMark进行赋值为出栈的节点

如果没有"//判断当前栈顶元素的右是否被标记"这一判断条件  程序将会出现死循环

//后序遍历
void houxubianli(BinaryTree* pRoot)
{
	if (NULL == pRoot)
		return;
	stack<BinaryTree*>st;
	BinaryTree* pMark = NULL;

	while (1)
	{

		while (pRoot)
		{
			
				st.push(pRoot);
				
			
			pRoot = pRoot->Left;

			

		}

		if (st.empty() == true)
		{
			cout << endl;
			return;
		} 
		//判断当前栈顶元素的右是否被标记  或当 前栈顶元素是否有右
		if (st.top()->Right == NULL || st.top()->Right == pMark)
		{
			pMark = st.top();
			st.pop();
			cout << pMark->id << " ";
		}
		//执行当前元素的右
		else
		{
			pRoot = st.top();
			pRoot = pRoot->Right;

		}
		
	}
	
}

完整代码如下

#include<iostream>
#include<stack>
#include<stdlib.h>
#include<queue>
using namespace std;




struct BinaryTree
{
	int id;
	BinaryTree* Left;
	BinaryTree* Right;

};

//前序遍历
void qianxubianli(BinaryTree*pRoot)
{
	//判断当前树是否为空
	if (NULL == pRoot)
		return;
	//定义一个栈用作工具
	stack<BinaryTree*>st;
	
	while (1)
	{
		//
		while (pRoot)
		{
			//打印当前节点并入栈
			cout << pRoot->id << " ";
			
			st.push(pRoot);  
			
				pRoot = pRoot->Left;
			
		}
		//左为空  判断当前栈是否为空   为空则遍历结束
		if (st.empty() == true)
		{
			cout << endl;
			return;
		}

		pRoot = st.top();
		st.pop();
		pRoot = pRoot->Right;
				
				
			
	
		
	}
	
	
	
}

//中序遍历
void zhongxubianli(BinaryTree* pRoot)
{
	if (NULL == pRoot)
		return;
	stack<BinaryTree*>st;

	while (1)
	{
		
		while (pRoot)
		{
			
			st.push(pRoot);

			pRoot = pRoot->Left;

		}
		
		if (st.empty() == true)
		{
			cout << endl;
			return;
		}
		
		pRoot = st.top();
		st.pop();
		
		cout << pRoot->id << " ";
		pRoot = pRoot->Right;
		
		
		
		





	}
	


}

//后序遍历
void houxubianli(BinaryTree* pRoot)
{
	if (NULL == pRoot)
		return;
	stack<BinaryTree*>st;
	BinaryTree* pMark = NULL;

	while (1)
	{

		while (pRoot)
		{
			
				st.push(pRoot);
				
			
			pRoot = pRoot->Left;

			

		}

		if (st.empty() == true)
		{
			cout << endl;
			return;
		} 
		//判断当前栈顶元素的右是否被标记  或当 前栈顶元素是否有右
		if (st.top()->Right == NULL || st.top()->Right == pMark)
		{
			pMark = st.top();
			st.pop();
			cout << pMark->id << " ";
		}
		//执行当前元素的右
		else
		{
			pRoot = st.top();
			pRoot = pRoot->Right;

		}
		
	}
	
}

//程序遍历
void chengxubianli(BinaryTree* pRoot)
{
	if (NULL == pRoot)
	{
		
		return;
	}
		
	queue<BinaryTree*> Qu;
	Qu.push(pRoot);
	
	while (Qu.empty()==0)

	{
		pRoot=Qu.front();
		Qu.pop();
		if (pRoot!=NULL)
		{
			cout << pRoot->id << " ";
			
			Qu.push(pRoot->Right);
			Qu.push(pRoot->Left);
		}
		
	}
	cout << endl;
	
}
int main()
{
	//根
	BinaryTree* Boot = new BinaryTree;
	Boot->id = 1;
	//根的左
	Boot->Left = new BinaryTree;
	Boot->Left->id = 2;
	//根的左的左
	Boot->Left->Left = new BinaryTree;
	Boot->Left->Left->id = 4;
	Boot->Left->Left->Left = NULL;
	Boot->Left->Left->Right = NULL;
	//左的右
	Boot->Left->Right = new BinaryTree;
	Boot->Left->Right->id = 5;
	Boot->Left->Right->Left = NULL;
	Boot->Left->Right->Right = NULL;

	//根的右
	Boot->Right = new BinaryTree;
	Boot->Right->id = 3;
	//右的左
	Boot->Right->Left = new BinaryTree;
	Boot->Right->Left->id = 6;
	Boot->Right->Left->Left = NULL;
	Boot->Right->Left->Right = NULL;
	//右的右
	Boot->Right->Right = new BinaryTree;
	Boot->Right->Right->id = 7;
	Boot->Right->Right->Left = NULL;
	Boot->Right->Right->Right = NULL;


	qianxubianli(Boot);
	zhongxubianli(Boot);
	houxubianli(Boot);
	chengxubianli(Boot);

	return 0;
}

执行结果如图:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值