算法题目刷题:1 树的非递归遍历

本文深入探讨了二叉树的前序、中序、后序遍历算法,包括递归与非递归实现方式。重点讲解了非递归遍历的栈辅助技巧,如先序遍历的根节点打印时机,中序遍历的左子树优先策略,以及后序遍历的双栈法。通过具体代码实例,帮助读者理解并掌握二叉树遍历的核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

二叉树的前中后序遍历(递归,非递归),时间复杂度为N,空间复杂度为N

思路:

1)二叉树的三种递归遍历,只是递归遍历树的时候,打印的时机不同,第一次遍历结点的时候打印,为先序遍历。第二次为中序,第三次为后序。(在树的递归的时候,每个结点都会遍历三次)。

2)二叉树的非递归遍历,用栈来辅助这三次遍历的过程

先序遍历非递归版本:

思路:把根节点压入栈中,此时就是栈顶元素,然后,弹出就打印,依次压入弹出的根节点的右孩子,左孩子。然后重复上面的过程。这个程序终止的条件是,栈变为了空。

void preOrderUNRecur(Node *root )//这里的root代表的是栈最上面的元素。
	{
		
		if(root != NULL)
		{
			stack <Node*> st;
			st.push( root  );
			while( !st.empty() )
			{
				root  = st.top();
				cout<<root->val<<" ";
				st.pop();
				if(root->right !=NULL)
				{
					st.push(root->right );
				}
				if(root->left !=NULL)
				{
					st.push(root->left );
				}
			}				 
		}

中序遍历非递归版本:

思路:充分利用两个空孩子的空档,输出打印左结点,根节点,神奇

void midOrderUNRecur(Node *root )
	{
		if(root != NULL)
		{
			stack <Node*> st;
			while( !st.empty() || root!=NULL)
			{
				if(root!=NULL)
				{
					st.push(root);
					root=root->left;
				}
				else//充分利用两个空孩子
				{
					root=st.top();
					cout<<root->val<<" ";st.pop();
					root=root->right;
					
				}
			}
		}
	}

 

后序遍历非递归版本:

思路:用两个栈实现,保证第二个栈,装入根节点,再装入右结点,左结点。。。整个过程完全在模拟递归的使用套路。

void postOrderUNRecur(Node *head )
	{
		if(head!=NULL)
		{
			stack<Node * > s1;
			stack<Node * > s2;
			s1.push(head);
			while( !s1.empty() )
			{
				head = s1.top(); s1.pop();
				s2.push(head);
				if( head->left!=NULL)
				{
					s1.push(head->left);
				}
				if( head->right!=NULL)
				{
					s1.push(head->right);
				}
			}
			while(!s2.empty())
			{
				cout<<s2.top()->val<<" ";
				s2.pop();
			}
		}
	}

 总共的三个过程,去感受其神奇之处。做研究应该关注其本身(by左神),基本的东西就应该熟练掌握。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值