非递归遍历树的总结(前中后序)
递归,显而易见。
非递归,bfs,是用队列。
而前中后序,一般都是用栈。
一种很直观的方法是,采用一个flag,记录第几次进栈出栈,从而决定是否打印,决定下一个入栈的是左还是右子节点。
但是下面的方法,更近精简和巧妙。
https://discuss.leetcode.com/topic/30632/preorder-inorder-and-postorder-iteratively-summarization
把前、中、后三种遍历都总结了,而且没有用多余的flag。采用的技巧是同时判断栈和cur节点。
前序:

public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); Deque<TreeNode> stack = new ArrayDeque<>(); TreeNode p = root; while(!stack.isEmpty() || p != null) { if(p != null) { stack.push(p); result.add(p.val); // Add before going to children p = p.left; } else { TreeNode node = stack.pop(); p = node.right; } } return result; }
中序:

public List<Integer> inorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); Deque<TreeNode> stack = new ArrayDeque<>(); TreeNode p = root; while(!stack.isEmpty() || p != null) { if(p != null) { stack.push(p); p = p.left; } else { TreeNode node = stack.pop(); result.add(node.val); // Add after all left children p = node.right; } } return result; }
后序:

public List<Integer> postorderTraversal(TreeNode root) { LinkedList<Integer> result = new LinkedList<>(); Deque<TreeNode> stack = new ArrayDeque<>(); TreeNode p = root; while(!stack.isEmpty() || p != null) { if(p != null) { stack.push(p); result.addFirst(p.val); // Reverse the process of preorder p = p.right; // Reverse the process of preorder } else { TreeNode node = stack.pop(); p = node.left; // Reverse the process of preorder } } return result; }
另外,对于后序,有一种解法,是先打印,然后再反转。
https://discuss.leetcode.com/topic/2919/my-accepted-code-with-explaination-does-anyone-have-a-better-idea

class Solution { public: vector<int> postorderTraversal(TreeNode *root) { stack<TreeNode*> nodeStack; vector<int> result; //base case if(root==NULL) return result; nodeStack.push(root); while(!nodeStack.empty()) { TreeNode* node= nodeStack.top(); result.push_back(node->val); nodeStack.pop(); if(node->left) nodeStack.push(node->left); if(node->right) nodeStack.push(node->right); } reverse(result.begin(),result.end()); return result; }
也很巧妙。
上面这个解法,也是针对这道题目:
https://leetcode.com/problems/binary-tree-postorder-traversal/?tab=Description
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!