递归,显而易见。

非递归,bfs,是用队列。

而前中后序,一般都是用栈。

一种很直观的方法是,采用一个flag,记录第几次进栈出栈,从而决定是否打印,决定下一个入栈的是左还是右子节点。

 

但是下面的方法,更近精简和巧妙。

https://discuss.leetcode.com/topic/30632/preorder-inorder-and-postorder-iteratively-summarization

把前、中、后三种遍历都总结了,而且没有用多余的flag。采用的技巧是同时判断栈和cur节点。

前序:


非递归遍历树的总结(前中后序)_出栈非递归遍历树的总结(前中后序)_出栈_02


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;
}

View Code

中序:


非递归遍历树的总结(前中后序)_出栈非递归遍历树的总结(前中后序)_出栈_02


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;
}

View Code

后序:


非递归遍历树的总结(前中后序)_出栈非递归遍历树的总结(前中后序)_出栈_02


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;
}

View Code

 

另外,对于后序,有一种解法,是先打印,然后再反转。

https://discuss.leetcode.com/topic/2919/my-accepted-code-with-explaination-does-anyone-have-a-better-idea


非递归遍历树的总结(前中后序)_出栈非递归遍历树的总结(前中后序)_出栈_02


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;

}

View Code

 

也很巧妙。

 

上面这个解法,也是针对这道题目:

https://leetcode.com/problems/binary-tree-postorder-traversal/?tab=Description