Binary Tree Postorder Traversal
2016-02-24 22:14
302 查看
题目名称
145.Binary Tree Postorder Traversal
描述
Given a binary tree, return the postorder traversal of its nodes’ values.
For example:
Given binary tree
return [3,2,1].
Note: Recursive solution is trivial, could you do it iteratively?
分析
由后序遍历过程可知,采用一个栈保存需要返回的节点指针,先扫描根节点的所有左结点并一一进栈,出栈一个节点*b即当前节点,然后扫描该节点的右孩子节点并进栈,再扫描该右孩子结点的所有左结点并进栈。当一个节点的左右孩子结点均被访问后再访问该节点,如此这样,直到栈为空为止。
其中的难点是如何判断一个节点*b的右孩子节点已被访问过,为此用p保存刚刚访问过的节点(初值为NULL),若b->right == p或者b->right==NULL,说明*b的左右子树均被访问过,现在应访问*b。
从上述过程可知,栈中保存的是当前结点*b的所有祖先节点。对应的非递归算法如下:
C++代码
一个更好的算法
算法是这道题的讨论里面得票数最多的,他的解释是这样的:
Create an empty stack, Push root node to the stack.
Do following while stack is not empty.
2.1. pop an item from the stack and print it.
2.2. push the left child of popped item to stack.
2.3. push the right child of popped item to stack.
reverse the ouput.
145.Binary Tree Postorder Traversal
描述
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?
分析
由后序遍历过程可知,采用一个栈保存需要返回的节点指针,先扫描根节点的所有左结点并一一进栈,出栈一个节点*b即当前节点,然后扫描该节点的右孩子节点并进栈,再扫描该右孩子结点的所有左结点并进栈。当一个节点的左右孩子结点均被访问后再访问该节点,如此这样,直到栈为空为止。
其中的难点是如何判断一个节点*b的右孩子节点已被访问过,为此用p保存刚刚访问过的节点(初值为NULL),若b->right == p或者b->right==NULL,说明*b的左右子树均被访问过,现在应访问*b。
从上述过程可知,栈中保存的是当前结点*b的所有祖先节点。对应的非递归算法如下:
C++代码
/** * 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; if(!root) return res; stack<TreeNode *> st; TreeNode *p,*b=root; int flag = 0; st.push(b); while(!st.empty()) { while(b->left) { st.push(b->left); b=b->left; } p=NULL; flag = 1; while(!st.empty() && flag) { b = st.top(); if(b->right ==p || !b->right) { res.push_back(b->right); st.pop(); p=b; } else { b=b->right; st.push(b); flag=0; } } } return res; } };
一个更好的算法
算法是这道题的讨论里面得票数最多的,他的解释是这样的:
Create an empty stack, Push root node to the stack.
Do following while stack is not empty.
2.1. pop an item from the stack and print it.
2.2. push the left child of popped item to stack.
2.3. push the right child of popped item to stack.
reverse the ouput.
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; } };
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- 一波二叉树遍历问题的C++解答实例分享
- C++非递归队列实现二叉树的广度优先遍历
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- C#非递归先序遍历二叉树实例
- C++将二叉树转为双向链表及判断两个链表是否相交
- C++非递归建立二叉树实例
- C语言实现找出二叉树中某个值的所有路径的方法
- C++实现二叉树遍历序列的求解方法
- C语言实现二叉树遍历的迭代算法
- C++实现查找二叉树中和为某一值的所有路径的示例
- 用C语言判断一个二叉树是否为另一个的子结构
- C++实现二叉树非递归遍历方法实例总结
- C++二叉树结构的建立与基本操作
- 深入遍历二叉树的各种操作详解(非递归遍历)
- JavaScript数据结构和算法之二叉树详解
- java使用归并删除法删除二叉树中节点的方法
- Java中二叉树数据结构的实现示例