Leetcode#145 Binary Tree Postorder Traversal

原题地址

递归写法谁都会,看看非递归写法。

对于二叉树的前序和中序遍历的非递归写法都很简单,只需要一个最普通的栈即可实现,唯独后续遍历有点麻烦,如果不借助额外变量没法记住究竟遍历了几个儿子。所以,最直接的想法就是在栈中记录到底遍历了几个儿子。

代码:

 1 vector<int> postorderTraversal(TreeNode *root) {
 2         vector<int> path;
 3         stack<pair<TreeNode *, int> > st;
 4         
 5         st.push(pair<TreeNode *, int>(root, 0));
 6         while (!st.empty()) {
 7             pair<TreeNode *, int> top = st.top();
 8             st.pop();
 9             
10             if (!top.first)
11                 continue;
12             
13             if (top.second == 0) {
14                 top.second = 1;
15                 st.push(top);
16                 st.push(pair<TreeNode *, int>(top.first->left, 0));
17             }
18             else if (top.second == 1) {
19                 top.second = 2;
20                 st.push(top);
21                 st.push(pair<TreeNode *, int>(top.first->right, 0));
22             }
23             else if (top.second == 2) {
24                 path.push_back(top.first->val);
25             }
26         }
27         
28         return path;
29     }

另外还有一种技巧性比较强的写法,只使用普通的栈就可以做到。利用到了一个后续遍历的特点,即:

后续遍历序列中,父节点前面一定紧挨着他的儿子节点(如果有的话)

所以,额外保存一个prev变量代表前一个遍历的节点,就可以识别出上面的情况。如果prev节点是当前节点的儿子节点(或者当前节点没有儿子),说明当前节点的儿子节点都遍历过了,可以遍历父节点了。

如何更新维护prev呢?当一个节点输出后,将prev置为这个节点,这是因为如果prev是后续遍历序列中的前一个节点,那么这个prev节点必须是已经被输出的节点。

代码如下:

 1     vector<int> postorderTraversal(TreeNode *root) {
 2         vector<int> path;
 3         stack<TreeNode *> st;
 4         TreeNode *prev = NULL;
 5 
 6         st.push(root);
 7         while (!st.empty()) {
 8             TreeNode *node = st.top();
 9 
10             if (!node)
11                 st.pop();
12             else if ((!node->left && !node->right)
13                   || (prev && (node->left == prev || node->right == prev))) {
14                 path.push_back(node->val);
15                 st.pop();
16                 prev = node;
17             }
18             else {
19                 st.push(node->right);
20                 st.push(node->left);
21             }
22         }
23 
24         return path;
25     }

也就短了几行而已。。

原文地址:https://www.cnblogs.com/boring09/p/4234231.html