二叉树三种遍历算法的递归和非递归实现(C++)

struct BinaryTreeNode
{
	int m_nValue;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
};
//递归前序遍历
void PreOrder(BinaryTreeNode* pNode)
{
	if(pNode!=NULL)
	{
		cout<<pNode->m_nValue<<endl;
		PreOrder(pNode->m_pLeft);
		PreOrder(pNode->m_pRight);
	}
}
//非递归前序遍历
/*
根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。
即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,
若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树
*/
void PreOrder_loop(BinaryTreeNode* pNode)
{
	stack<BinaryTreeNode*> stackNode;
	while(!pNode||!stackNode.empty())
	{
		while(!pNode)
		{
			cout<<pNode->m_nValue<<endl;
			stackNode.push(pNode);
			pNode=pNode->m_pLeft;
		}
		if(!stackNode.empty())
		{
			pNode=stackNode.top();
			stackNode.pop();
			pNode=pNode->m_pRight;
		}
	}
}
//递归中序遍历
void InOrder(BinaryTreeNode* pNode)
{
	if(pNode!=NULL)
	{
		InOrder(pNode->m_pLeft);
		cout<<pNode->m_nValue<<endl;
		InOrder(pNode->m_pRight);
	}
}
//非递归中序遍历
/*
根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以看做一根结点,
然后继续访问其左孩子结点,直到遇到左孩子结点为空的结点才进行访问,然后按相同的规则访问其右子树。
*/
void InOrder_loop(BinaryTreeNode* pNode)
{
	stack<BinaryTreeNode*> stackNode;
	while(!pNode||!stackNode.empty())
	{
		while(!pNode)
		{
			stackNode.push(pNode);
			pNode=pNode->m_pLeft;
		}
		if(!stackNode.empty())
		{
			pNode=stackNode.top();
			cout<<pNode->m_nValue<<endl;
			stackNode.pop();
			pNode=pNode->m_pRight;
		}
	}
}
//递归后序遍历
void PostOrder(BinaryTreeNode* pNode)
{
	if(pNode!=NULL)
	{
		PostOrder(pNode->m_pLeft);
		PostOrder(pNode->m_pRight);
		cout<<pNode->m_nValue<<endl;
	}
}
//非递归后序遍历
/*
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,
则可以直接访问它;或者P 存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证 了每次取栈顶元素的时候,左孩子在右孩子前面被访问,
左孩子和右孩子都在根结点前面被访问。
*/
void PostOrder_loop(BinaryTreeNode* pNode)
{
	stack<BinaryTreeNode*> stackNode;
	BinaryTreeNode* cur;//当前节点
	BinaryTreeNode* pre=NULL;//前一次访问的结点
	stackNode.push(pNode);
	while(!stackNode.empty())
	{
		cur=stackNode.top();
		if((cur->m_pLeft==NULL&&cur->m_pRight==NULL) ||
		(pre!=NULL&&(pre==cur->m_pLeft ||pre==cur->m_pRight)))
		{
			cout<<cur->m_nValue<<endl;
			stackNode.pop();
			pre=cur;
		}
		else
		{
			if(cur->m_pRight!=NULL)
				stackNode.push(cur->m_pRight);
			if(cur->m_pLeft!=NULL)
				stackNode.push(cur->m_pLeft);
		}
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值