Leetcode 145. Binary Tree Postorder Traversal
来源:互联网 发布:2016年的网络流行词 编辑:程序博客网 时间:2024/04/28 04:10
题目描述:
Given a binary tree, return the postorder traversal of its nodes’ values.
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?
解题思路:
题目要求我们实现用迭代的方式后序遍历二叉树,这时候就需要使用到栈的数据结构, 我们基本的思想就是让他不断的向左走, 直到走到树的最左端, 然后回溯。 但是问题来了, 在回溯的过程中, 我如何才能判断我的右子树是否已经被遍历过了呢, ie,我应该在什么时候访问这个节点最合适?
想到这里, 我们想到图的遍历过程中, 有一个表记录着被访问过的节点的信息, 那么, 同样的我们也可以参考这样的思想, 用一个set结构记录节点的访问信息, 至此算法就出来了。
下面是我们的代码部分:
/** * 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) { stack<TreeNode *> mystack; set<TreeNode *> isvisited; vector<int> res; while (!mystack.empty() || root){ // 如果节点非空, 压栈 if (root){ mystack.push(root); root = root->left; } else{ // 只有当左子树遍历完了, 才到这里 TreeNode * top = mystack.top(); if (top->right == nullptr || isVisited(isvisited, top->right)){ // 右子树为空或者右子树已经被遍历过了, 更新访问表, 并输出 res.push_back(top->val); isvisited.insert(top); mystack.pop(); } else{ // 右子树没有被遍历过, 需要对右子树遍历 root = top->right; } } } return res; }private: inline bool isVisited(set<TreeNode *> & myset, TreeNode * data){ return (myset.find(data) == myset.end()) ? false : true; }};
然后我们查看了一下, 我们3个月前提交的代码, 发现思路是一样的, 不过当时是采用定义一个新的数据结构来记录左右子树的访问与否。
struct stackNode{ TreeNode * node; bool right; bool left; stackNode(TreeNode * x, bool bleft, bool bright) : node(x), left(bleft), right(bright){} };
相当于将原来的数据结构又做了一层封装。
代码如下:
//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 {private: struct stackNode{ TreeNode * node; bool right; bool left; stackNode(TreeNode * x, bool bleft, bool bright) : node(x), left(bleft), right(bright){} };public: vector<int> postorderTraversal(TreeNode* root) { if (root == nullptr) return vector<int>(); vector<int> res; stack<stackNode> mystack; while (root || !mystack.empty()){ if (root){ mystack.emplace(stackNode(root, true, false)); root = root->left; } else{ stackNode tmp = mystack.top(); root = tmp.node; mystack.pop(); if (tmp.right == false){ mystack.emplace(stackNode(tmp.node, true, true)); root = root->right; } else{ res.push_back(tmp.node->val); root = nullptr; } } } return res; }};
网上有大神的解法, 不需要使用访问表, 基本思想:
记录上次回溯的节点, 此时由于需要回溯, root == nullptr, 然后判断这个节点是否是当前栈顶节点的右节点, 就可以判断出当前节点的右子树是否已经被遍历过了。 特别巧妙的一种方法!!
vector<int> postorderTraversal(TreeNode* root) { vector<int> nodes; stack<TreeNode*> toVisit; TreeNode* curNode = root; TreeNode* lastNode = NULL; while (curNode || !toVisit.empty()) { if (curNode) { toVisit.push(curNode); curNode = curNode -> left; } else { TreeNode* topNode = toVisit.top(); if (topNode -> right && lastNode != topNode -> right) curNode = topNode -> right; else { nodes.push_back(topNode -> val); lastNode = topNode; toVisit.pop(); } } } return nodes;}
当然还有一种思路是使用 Morris 翻转, 这个算法没有仔细研究, 大家可以百度一下。
参考资料:
0 ms Clear C++ solutions — iterative, recursive, Morris traversal (3 different solutions!)
- [LeetCode]145.Binary Tree Postorder Traversal
- [leetcode] 145.Binary Tree Postorder Traversal
- 145. Binary Tree Postorder Traversal LeetCode
- Leetcode 145. Binary Tree Postorder Traversal
- [LeetCode]145. Binary Tree Postorder Traversal
- Leetcode 145. Binary Tree Postorder Traversal
- leetcode 145. Binary Tree Postorder Traversal
- LeetCode 145. Binary Tree Postorder Traversal
- LeetCode-145.Binary Tree Postorder Traversal
- [leetcode] 145. Binary Tree Postorder Traversal
- LeetCode 145. Binary Tree Postorder Traversal
- leetcode 145. Binary Tree Postorder Traversal
- [LeetCode]problem 145. Binary Tree Postorder Traversal
- Leetcode 145. Binary Tree Postorder Traversal
- [LeetCode] 145. Binary Tree Postorder Traversal
- LeetCode 145. Binary Tree Postorder Traversal
- LeetCode 145. Binary Tree Postorder Traversal
- LeetCode:145. Binary Tree Postorder Traversal
- android:inputType常用取值
- Select From (Select from) as Alias
- Consecutive Numbers
- Xcode磁盘空间大清理
- 代码零件
- Leetcode 145. Binary Tree Postorder Traversal
- IOS 仿自带计算器
- 自增自减操作符
- HTML基本语法
- hadoop启动报错-namenode无法启动-GC overhead limit exceeded
- Linux shell 学习(一)
- Employees Earning More Than Their Managers
- jsp界面上日期格式的处理
- 正则表达式(银行卡号,手机号码,车牌号,身份证号)