【数据结构】二叉树的非递归遍历

typedef struct TNode
{
	struct TNode* left;
	struct TNode* right;
	int data;
}*BinTree; 

1、先序遍历

前序遍历按照“根结点-左孩子-右孩子”的顺序进行遍历。
具体算法:先遍历左孩子,并输出。当左孩子遍历完后,取栈顶,并借助栈顶找到右孩子。此时循环还没有结束,再遍历它的左子树,右孩子直至孩子全部遍历结束。

void PreorderTraversal(BinTree T)   //前序遍历 
{
	if(!T) return;
	BinTree p = T;
	stack<BinTree> s;
	while(!s.empty() || p)
	{
		//遍历左孩子并输出 
		if(p)
		{
			cout<<p->data<<" ";		 
			s.push(p);
			p = p->left;
		}
		//左孩子遍历结束,取栈顶,找右孩子 
		else
		{
			p = s.top();
			p = p->right;
			s.pop();
		}
	}
}

2、中序遍历

中序遍历按照左孩子-根节点-右孩子”的顺序进行遍历。
具体算法:先遍历左孩子,先不急着输出。当左孩子遍历完后,取栈顶并输出栈顶元素,借助栈顶找到右孩子。此时循环还没有结束,再按照“左-根-右”顺序遍历右孩子,直至孩子全部遍历结束。

void InorderTraversal(BinTree T)	//中序遍历 
{
	if(!T) return;
	BinTree p = T;
	stack<BinTree> s;
	while(!s.empty() || p)
	{
		//先遍历左孩子 
		if(p)
		{
			s.push(p);
			p = p->left;
		}
		//左孩子遍历完,输出根节点,找到右孩子 
		else
		{
			p = s.top();
			cout<<p->data<<" ";
			p = p->right;
			s.pop();
		}
	}
} 

3、后序遍历

后序遍历按照左孩子-右孩子-根节点”的顺序进行遍历。
后序遍历的难点在于:需要判断上次访问的节点是左孩子,还是右孩子。若是左孩子,则需跳过根节点,先访问右孩子,再回头访问根节点;若是右孩子,则直接访问根节点。因为涉及到判断节点的访问状态,所以后序遍历就比较难写。
现在有个很巧妙的方法:

后序:左->右->根

那么可以把后序按:根->右->左 遍历,然后再反转一下即可

void PostorderTraversal(BinTree T)		//后序遍历 
{
	if(!T) return;
	stack<BinTree> s1;
	stack<BinTree> s2;
	BinTree p;
	s1.push(T);
	while(!s1.empty())
	{
		p = s1.top();
		s1.pop();	//根节点访问完,出栈s1,进栈s2 
		s2.push(p);
		//先按left right进栈s1, 则之后取s1栈顶 便是 right left 
		if(p->left) s1.push(p->left);
		if(p->right) s1.push(p->right);
	}
	while(!s2.empty())
	{
		cout<<s2.top()->data<<" ";
		s2.pop();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值