二叉树遍历之迭代遍历

前文我们简述了 二叉树遍历之递归遍历

其实用到的是递归中自己的栈来完成的,那么我们要是用迭代的话也是要通过自己的栈来完成

前序遍历:根 左 右

我们在递归遍历时通过前序遍历的原理图示展示了整个过程:

根节点第一次出栈就可以打印了,然后再来分别出栈左右子节点

void preorderIteration(struct TreeNode* root, MyStack *stk)
{
	if(root == NULL)
		return;
		
	myStackPush(stk, root);
	
	while( ! myStackEmpty(stk) )
	{
		root = myStackTop(stk);
		myStackPop(stk);
		printf("val=%d\n", root->val);
		
		if(root->right)
			myStackPush(stk, root->right);
		
		if(root->left)
			myStackPush(stk, root->left);	
	}
}

中序遍历:左 根 右

我们遇见左节点时还要看有没有左子节点,一直要到最左边的叶子为止

所以根节点先入栈,然后持续对左子节点压栈,直到左子节点为NULL,这个时候就可以出栈左子节点,打印其值

左边节点值打印完成,如果其没有右子节点,那么再出栈的话就是其父节点(根)

如果有右子节点,那么该左节点视为子树的根节点,对右子树进行重复逻辑

void inorderIteration(struct TreeNode* root, MyStack *stk)
{
	if(root == NULL)
		return;
	
	while(! myStackEmpty(stk) || root != NULL)
	{
		if(root != NULL)
		{
			myStackPush(stk, root);
			root = root->left;
		}
		else
		{
			root = myStackTop(stk);
			myStackPop(stk);
			printf("val=%d\n", root->val);
			
			root = root->right;
		}
	
	}
}

1. 依次入栈根,左子节点,直到没有左子节点

2. 出栈,节点 4 没有右子节点,再出栈就是其父节点 2,同样节点 2也没有右子节点,再出栈就是节点 1

3. 节点 1 有 右子节点,那么就开始处理右子树,整个过程逻辑一样

 

后序遍历:左,右,根

与前面两种方式不一样,我们在处理完左树后,根节点还不能打印

除非根节点没有右子树,或者右子树已经被打印了,才能打印根节点

所以根节点会进行二次入栈,当第二次出栈的时候通过比较临时节点变量(保存压栈时的根节点)与当前根节点是否一样,一样表示已经处理完,这个时候就能够打印当前根节点

void postorderIteration(struct TreeNode* root, MyStack *stk)
{
	if(root == NULL)
		return;
		
	struct TreeNode* prev = NULL;
	
	while(! myStackEmpty(stk) || root != NULL)
	{
		while(root != NULL)
		{
				myStackPush(stk, root);
				root = root->left;
		}
		
		root = myStackTop(stk);
		myStackPop(stk);
		
		if(root->right == NULL || root->right == prev)
		{
			printf("val=%d\n", root->val);
			prev = root;
			root = NULL;
		}
		else
		{
			myStackPush(stk, root);
			root = root->right;
		}
	}	
	
}

1. 根节点开始压栈,完成左子节点的压栈

2. 出栈,节点 4 没有右子节点,可以打印值,继续出栈节点 2,也没有右子节点打印值

3. 节点 1 出栈后发现右右子节点,并且右子节点还未处理,第二次压栈

4. 处理节点 1 的右子树,逻辑一样。节点 3 同样进行了 二次压栈

5. 继续处理右子节点直至完成后才可以打印 根节点

 

更多数据结构详解

二叉树迭代遍历算法主要有三种:前序遍历、中序遍历和后序遍历。下面分别介绍这三种算法的迭代实现方法: 1. 前序遍历迭代算法: 前序遍历的顺序是根节点 -> 左子 -> 右子。使用迭代算法实现前序遍历时,可以通过栈来辅助实现。具体步骤如下: 1)将根节点入栈。 2)当栈不为空时,循环执行以下操作: a) 弹出栈顶节点,并将其值加入结果列表。 b) 若右子节点存在,则将右子节点入栈。 c) 若左子节点存在,则将左子节点入栈。 3)返回结果列表。 2. 中序遍历迭代算法: 中序遍历的顺序是左子 -> 根节点 -> 右子。使用迭代算法实现中序遍历时,同样可以通过栈来辅助实现。具体步骤如下: 1)初始化一个空栈,并将当前节点置为根节点。 2)循环执行以下操作,直到栈为空: a) 将当前节点及其所有左子节点依次入栈,直到最左叶子节点。 b) 弹出栈顶节点,并将其值加入结果列表。 c) 若弹出节点存在右子节点,则将右子节点置为当前节点。 3)返回结果列表。 3. 后序遍历迭代算法: 后序遍历的顺序是左子 -> 右子 -> 根节点。使用迭代算法实现后序遍历时,需要使用两个栈来辅助实现。具体步骤如下: 1)初始化两个空栈,分别为stack1和stack2。将根节点入栈stack1。 2)当stack1不为空时,循环执行以下操作: a) 弹出stack1的栈顶节点,并将其左子节点和右子节点依次入栈stack1。 b) 将弹出的节点压入stack2。 3)当stack1为空时,将stack2中的节点依次弹出并加入结果列表。 4)返回结果列表。 以上是三种常用的二叉树遍历迭代算法,根据不同的需求可以选择相应的算法进行实现。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值