二叉树遍历非递归写法

来源:http://www.cnblogs.com/BaroC/p/5188545.html

遍历的非递归实现是用栈来实现的,因为栈能提供先入后出。而对于层序遍历,由于需要遵循层的顺序,使用队列。

1.先序遍历(中左右)

初始化:根节点入栈。

循环:出栈一个节点,访问这个节点,然后把这个节点的右子树,左子树入栈

(由于栈先入后出,所以最后的顺序还是中-》左-》右)

Push(T,s);
while(!Empty(s)){
	Tree temp = Pop(s);
	visit(temp);
	Push(temp->Right,s);
	Push(temp->Left,s);
}

2.后序遍历(左右中)

双栈实现

初始化:根节点入栈

循环:出栈一个节点,把这个节点的右子树入栈1,然后把这个节点的左子树入栈1,把根节点放入栈2

放入栈2的顺序是根-》右-》左

再访问一次就是左右中了


完成循环以后,访问顺序在栈1中的顺序是对的

循环2:访问这个栈


<pre name="code" class="python">Push(T,S1)
while(!Empty(S1)){
	Tree temp = Pop(S1);
	Push(temp->Left,S1);
	Push(temp->Right,S1);
	Push(temp,S2);
}
while(!Empty(S2)){
	Tree temp = Pop(S2);
	visite(temp);
}


 

3.中序遍历(左中右)

中序遍历稍微复杂,使用一个指针p指向下一个待访问的节点,p初始化为根节点。在每次循环中执行以下操作:

  • 如果p非空,则把p入栈,p变为p的左儿子。
  • 如果p为空,说明已经向左走到尽头了,弹出当前栈顶元素,进行访问,并把p更新为其右儿子。

也就是说,其实这种做法是先把根节点的所有左子节点全部入栈。这时候就要防止左子节点的重复访问。

下面的代码是错的,因为会形成循环访问,

Push(T,S1)
p = T;
while(!Empty(S1)){
	if(P->Left){
		P=P->Left;
		Push(P,S1);
	}
	else{
		visit(P);
		if(P->right){
			P=P->right;
			Push(P,S1);
		}
		else{
			P=Pop(S1);
		}
	}

}

void inorder2(Node *root)//非递归中序遍历
{
	stack<Node *> stk;
	Node *p = root;
	while (p != NULL || !stk.empty())
	{
		if (p != NULL)
			stk.push(p), p = p->left;
		else
		{
			p = stk.top(); stk.pop();
			printf("%d ", p->val);
			p = p->right;
		}
	}
}
(上面的代码每次都做到了如果有左子节点,一定要访问到底的要求)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值