树——二叉树的中序遍历(非递归)

本文介绍了一种使用非递归方式实现二叉树中序遍历的方法,并提供了详细的Java代码实现。通过栈结构来辅助遍历过程,有效地实现了二叉树节点的访问。

思路:

二叉树的中序非递归遍历和前序非递归遍历类似。


代码如下:

import java.util.*;
public class Solution {
    public ArrayList<Integer> inorderTraversal(TreeNode root) {
        ArrayList<Integer> array=new ArrayList();
        Stack<TreeNode> stack=new Stack();
        if(root == null)
            return array;
        TreeNode node=root;
        while(node!=null||!stack.empty())
            {
            while(node!=null)
                {
                stack.push(node);
                node=node.left;
            }
            if(node == null&&!stack.empty())
                {
                TreeNode temp=stack.pop();
                array.add(temp.val);
                node=temp.right;
            }
        }
        return array;
    }
}




### 二叉树非递归遍历 #### 非递归序遍历 对于二叉树非递归序遍历,可以利用栈来保存节点指针。每次遇到一个新的节点时,先处理这个节点(打印或记录其值),再将其右孩子压入栈中,最后将左孩子作为当前节点继续这一过程直到完成整个遍历。 ```c void preOrderTraversalNonRecursive(TreeNode* root) { std::stack<TreeNode*> nodeStack; TreeNode *current = root; while (current != NULL || !nodeStack.empty()) { // 访问并推进到最左边路径上的所有节点 while (current != NULL) { printf("%d ", current->val); // 处理当前节点 nodeStack.push(current); current = current->left; // 转向左侧分支 } // 当到达叶节点后回溯至上一层次 if (!nodeStack.empty()) { current = nodeStack.top(); nodeStack.pop(); // 继续探索右侧分支 current = current->right; } } } ``` 此段代码展示了如何通过显式维护一个栈来进行非递归形式下的前序遍历操作[^2]。 #### 非递归序遍历 同样采用栈辅助实现非递归版本的中序遍历时,区别在于只在第二次遇见某个节点时才对其进行访问。即当从它的左子返回时才会真正输出该节点的数据。 ```c void inOrderTraversalNonRecursive(TreeNode* root) { std::stack<TreeNode*> nodeStack; TreeNode *current = root; while (current != NULL || !nodeStack.empty()) { // 推进至最深部的左叶子之前暂不作任何处理 while (current != NULL) { nodeStack.push(current); current = current->left; } // 开始自底向上逐层弹出元素并访问之 if (!nodeStack.empty()) { current = nodeStack.top(); nodeStack.pop(); printf("%d ", current->val); // 完成对该节点的操作后再转向右边部分 current = current->right; } } } ``` 这段程实现了基于栈结构控制流程走向从而达到模拟函数调用堆栈效果的目的,在此基础上完成了对一棵给定二叉树按中依次访问各个顶点的任务[^3]。 #### 非递归序遍历 相比于其他两种遍历模式而言,非递归版的后续遍历逻辑上更为复杂一些。这里介绍的方法是借助两个栈S1和S2共同协作完成任务:首先按照常规方式构建起第一个栈;接着不断取出其中顶部项放入第二个栈内直至前者为空为止;最终由后者逆给出所需的结果列即可满足题目要求。 ```c void postOrderTraversalNonRecursive(TreeNode* root) { if (root == nullptr) return; std::stack<TreeNode*> s1, s2; s1.push(root); while (!s1.empty()) { TreeNode* temp = s1.top(); s1.pop(); s2.push(temp); if (temp->left != nullptr) s1.push(temp->left); if (temp->right != nullptr) s1.push(temp->right); } while (!s2.empty()) { TreeNode* temp = s2.top(); s2.pop(); printf("%d ", temp->val); } } ``` 上述代码片段提供了一种有效途径用于解决此类问题——它巧妙运用双端队列特性简化了原本棘手之处,并确保能够正确无误地执行完整的后序遍历动作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值