二叉树的三种遍历方式非递归

## 二叉树的遍历需要把当前根节点和左右子树抽象成只有一个根节点和一个左子树,一个右子树的情况

##套路 二叉树的遍历先序中序后序无非是根节点的处理顺序不同,三种遍历方式都有一个相同的逻辑流程,不管怎么样首先将左子树入栈,遍历无非是处理的时机不一样。

1. 先序遍历   根节点的处理顺序和进栈的顺序一致,即进栈并且处理根节点

2. 中序遍历 左节点处理完成之后处理根节点,在程序中就是出栈之后处理根节点

3. 后序遍历(与先序和中序不同)

 栈顶的元素是否处理需要满足条件,出栈入栈的顺序不能简单的和处理根节点的顺序一致,需要记住最近依次处理的结点,

满足条件 1. 栈顶元素的右子树为空 2. 栈顶元素的右子树被处理过

先序和中序代码基本一致:

void search_order(BTNode* node)
{
	QStack<BTNode*> stack_;
	BTNode* curNode = node;
	if (node)
		// 不管三七二十一 左子树直接入栈
	{
		while (curNode)
		{
			//printf(" %c", curNode->data.toLatin1()); // 进栈之前处理先序
			stack_.push_back(curNode);
			curNode = curNode->lchild;
		}
		while (!stack_.empty())
		{
			curNode = stack_.top(); // 出栈即表示栈顶元素的左子树已经处理完毕
			stack_.pop();
            //printf(" %c", curNode->data.toLatin1()); // 出栈之后处理 中序
			curNode = curNode->rchild;


			while (curNode)
			{
				//printf(" %c ", curNode->data.toLatin1()); // 进栈之前处理先序
				stack_.push(curNode);
				curNode = curNode->lchild;
			}

		}
		printf("\n");
	}
	
}

后续遍历:

void Postorder(BTNode* node)
{

	QStack<BTNode*> stack_;
	BTNode* curNode = node;
	BTNode* lastNode = nullptr;
	if (curNode)
	{
		while (curNode)
		{
			stack_.push(curNode);
			curNode = curNode->lchild;
		}

		while (!stack_.empty()) {
			curNode = stack_.top();
			// 当前结点需要出栈的条件
			//① 已访问的结点为当前结点的右节点 
			// ② 当前结点为叶子结点
			// ③ 已访问的结点为栈顶元素的左节点 并且有栈顶元素的叶节点为空

			// 以上三个添加可以合并  栈顶元素的右子树为空,或者栈顶元素的右节点为已访问的结点
			/*if ( (!curNode->lchild && !curNode->rchild) 
				|| (curNode->rchild == lastNode) 
				|| (curNode->lchild == lastNode && curNode->rchild == NULL))*/
               if( curNode->rchild == NULL || curNode->rchild == lastNode)
			{
				printf(" %c ", curNode->data.toLatin1());
				lastNode = curNode;
				stack_.pop();
			}
			else
			{
				curNode = curNode->rchild;
				while (curNode)
				{
					stack_.push(curNode);
					curNode = curNode->lchild;
				}
			}
		}
	}
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值