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     }

 

也就短了几行而已。。

你可能感兴趣的:(LeetCode)