Binary Tree Postorder Traversal——重要的基本的算法
2015-08-23 21:14
459 查看
Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree
return
Note: Recursive solution is trivial, could you do it iteratively?
这道题想了很久,后序遍历应该是最麻烦的吧,最容易想到的方法就是直接设置标志位。
相比于前序遍历,后续遍历思维上难度要大些,前序遍历是通过一个stack,首先压入父亲结点,然后弹出父亲结点,并输出它的value,之后压人其右儿子,左儿子即可。然而后序遍历结点的访问顺序是:左儿子 -> 右儿子 -> 自己。那么一个结点需要两种情况下才能够输出:第一,它已经是叶子结点;第二,它不是叶子结点,但是它的儿子已经输出过。那么基于此我们只需要记录一下当前输出的结点即可。对于一个新的结点,如果它不是叶子结点,儿子也没有访问,那么就需要将它的右儿子,左儿子压入。如果它满足输出条件,则输出它,并记录下当前输出结点。输出在stack为空时结束。
网上看到一种简洁的方法,如果一个节点的左子树或右子树入栈后,就将其相应的左子树或右子树设置为NULL,思想简单,代码也简单,代码如下:
设立标志位的解法如下:
For example:
Given binary tree
{1,#,2,3},
1 \ 2 / 3
return
[3,2,1].
Note: Recursive solution is trivial, could you do it iteratively?
这道题想了很久,后序遍历应该是最麻烦的吧,最容易想到的方法就是直接设置标志位。
相比于前序遍历,后续遍历思维上难度要大些,前序遍历是通过一个stack,首先压入父亲结点,然后弹出父亲结点,并输出它的value,之后压人其右儿子,左儿子即可。然而后序遍历结点的访问顺序是:左儿子 -> 右儿子 -> 自己。那么一个结点需要两种情况下才能够输出:第一,它已经是叶子结点;第二,它不是叶子结点,但是它的儿子已经输出过。那么基于此我们只需要记录一下当前输出的结点即可。对于一个新的结点,如果它不是叶子结点,儿子也没有访问,那么就需要将它的右儿子,左儿子压入。如果它满足输出条件,则输出它,并记录下当前输出结点。输出在stack为空时结束。
网上看到一种简洁的方法,如果一个节点的左子树或右子树入栈后,就将其相应的左子树或右子树设置为NULL,思想简单,代码也简单,代码如下:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<int> postorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> stk; TreeNode* flag=root; if(root==NULL) return res; stk.push(root); while(!stk.empty()) { flag=stk.top(); if(flag->left!=NULL) { stk.push(flag->left); flag->left=NULL; } else if(flag->right!=NULL) { stk.push(flag->right); flag->right=NULL; } else { res.push_back(flag->val); stk.pop(); } } return res; } };
设立标志位的解法如下:
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<int> postorderTraversal(TreeNode *root) { vector<int> result; stack<TreeNode*> node; stack<int> nodeStatus; if(root != NULL){ node.push(root); nodeStatus.push(0); } while(!node.empty()){ TreeNode* n = node.top(); node.pop(); int status = nodeStatus.top(); nodeStatus.pop(); if(status == 0){ node.push(n); nodeStatus.push(1); if(n->right != NULL){ node.push(n->right); nodeStatus.push(0); } if(n->left != NULL){ node.push(n->left); nodeStatus.push(0); } } else{ result.push_back(n->val); } } return result; }
相关文章推荐
- var_export 与 var_dump的不同
- AutoCAD2014打开闪退的解决办法
- 分段压缩
- python笔记 4
- Ubuntu学习之Linux文件和目录管理
- HDU1024 Max Sum Plus Plus(DP动态规划 最大子串和增强版)
- 九度oj 1136
- [LeetCode] Sort Colors(!!两个指针)
- hdu 1385 Minimum Transport Cost(最短路,floyd打印字典序路径)
- 裸机开发前准备
- 基于iOS的OpenCV之人脸检测(二)
- CentOS6.5实现PXE+Kickstart无人值守安装操作系统
- hdu 5420 Victor and Proposition 线段树建图+强连通分量
- Java学习笔记----容器
- 连接postgresql数据库
- 8.23单词
- C# 之 FTP服务器中文件上传与下载(二)
- HDU Victor and World (最短路+状态压缩)
- 触摸时白色圆圈的中心不在十字架中心的问题
- c++返回引用和返回对象的区别