二叉树的前序、中序、后续、层序遍历(包含递归与非递归)

递归形式

递归形式遍历比较简单,不做详细论述。
前序遍历

void  Preorder(treenode* root)   //前序
{
	if (root != NULL)
	{
		printf("%c", root->data);
		Preorder(root->left);
		Preorder(root->right);
	}

中序遍历

}
void  Inorder(treenode* root)    //中序
{
	if (root != NULL)
	{	
		Inorder(root->left);
		printf("%c", root->data);
		Inorder(root->right);
	}

}

后序遍历

void  Postorder(treenode* root)     //后序
{
	if (root != NULL)
	{
		Postorder(root->left);
		Postorder(root->right);
		printf("%c", root->data);
	}
}

非递归形式

前序遍历
开始不断向左孩子遍历并入栈,在入栈的同时打印节点数据,直到左孩子为空,此时获取栈顶节点,并将其出栈,判断其有无右孩子,如果无右孩子,就再次获取栈顶节点并出栈,重复上述操作;如果有右孩子就将其入栈,并不断遍历其左孩子直到为空,重复上述操作,直到栈为空。
在这里插入图片描述

void PreOrder(treenode* root)
{
	if (root == NULL)
		return;
	treenode* p = root;
	stack<treenode *> s;
	while (!s.empty() || p)
	{
		//边遍历边打印,并存入栈中
		while (p)
		{
			printf("%c ", p->data);
			s.push(p);
			p = p->left;
		}
		//当p为空时,说明根和左子树都遍历完了,进入右子树
		if (!s.empty())
		{
			p = s.top();
			s.pop();
			p = p->right;
		}
	}
}

中序遍历
从根节点开始不断向左孩子遍历并入栈,直到为空,只要没有左孩子就出栈,在出栈的同时就打印节点数据,此时在判断出栈节点是否有右孩子,如果有右孩子重复上述操作继续向左孩子遍历,如果没有就出栈,重复上述操作判断有无右孩子,直到栈为空就退出遍历。
在这里插入图片描述

void InOrder(treenode* root)
{
	//空树
	if (root == NULL)
		return;
	//树非空
	treenode* p = root;
	stack<treenode *> s;
	while (!s.empty() || p)
	{
		//一直遍历到左子树最下边,边遍历边保存根节点到栈中
		while (p)
		{
			s.push(p);
			p = p->left;
		}
		//当p为空时,说明已经到达左子树最下边,这时需要出栈了
		if (!s.empty())
		{
			p = s.top();
			s.pop();
			printf("%c ", p->data);
			//进入右子树
			p = p->right;
		}
	}
}

后序遍历
后续在理解上较为难,用两个栈s1,s2更为直观,便于理解。
首先将根节点放入s2,再将其左右孩子放入s1中,一定要先放入左孩子,再放入右孩子,此时在获取s1栈顶节点并出栈,判断其是否有左右孩子,只要有孩子就将该节点入栈s2,并将该节点左右孩子放入s1中;如果该节点无左右孩子那么直接出栈s2并入栈s1,重复上述操作直到s1为空,在将s2从栈顶打印到栈底便是后续遍历
在这里插入图片描述

void PostOrder(treenode *root)
{

	stack<treenode *>s1, s2;
	treenode *cur=root; 
	s1.push(cur);//入栈根节点
	while (!s1.empty())
	{
		cur = s1.top();
		//出栈s1入栈s2
		s1.pop();
		s2.push(cur);
		//判断是否有左右孩子,有则入栈s1
		if (cur->left)
			s1.push(cur->left);
		if (cur->right)
			s1.push(cur->right);
	}
	while (!s2.empty())
	{
		printf("%c ", s2.top()->data);//打印s2
		s2.pop();
	}
}

层序遍历
层序遍历需要用到队列,先入队根节点,在出队,将其左右孩子入队,依次出队入队操作,只要该节点有孩子就入队,再出队的同时打印节点数据
在这里插入图片描述

void sequence(treenode *root)
{
	deque<treenode *>q;
	treenode *cur = root;
	q.push_back(cur);//根节点入队
	while (!q.empty())
	{
		cur = q.front();//获取队头
		q.pop_front();
		printf("%c ", cur->data);
		//孩子入队
		if (cur->left)
			q.push_back(cur->left);
		if (cur->right)
			q.push_back(cur->right);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值