用递归的方法对给定的二叉树进行后序遍历。
例如:
给定的二叉树为{1,#,2,3},
返回[3,2,1].
/* 这个解法可能是最佳实践,思路清晰,易于理解。
* 核心思想是用栈做辅助空间,先从根往左一直入栈,直到为空,然后判断栈顶元素的右孩子,如果不为空且未被访问过,
* 则从它开始重复左孩子入栈的过程;否则说明此时栈顶为要访问的节点(因为左右孩子都是要么为空要么已访问过了),
* 出栈然后访问即可,接下来再判断栈顶元素的右孩子...直到栈空。
*/
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> postorderTraversal(TreeNode root) {
TreeNode p = root, r = null; //P记录当前节点,r用来记录上一次访问的节点
Stack<TreeNode> s = new Stack<TreeNode>();
ArrayList<Integer> list = new ArrayList<Integer>();
while(p != null || !s.isEmpty()) {
if(p != null) { //左孩子一直入栈,直到左孩子为空
s.push(p);
p = p.left;
} else {
p = s.peek();
p = p.right;
if(p != null && p != r) { //如果栈顶元素的右孩子不为空,且未被访问过
s.push(p); //则右孩子进栈,然后重复左孩子一直进栈直到为空的过程
p = p.left;
} else {
p = s.pop(); //否则出栈,访问,r记录刚刚访问的节点
list.add(p.val);
r = p;
p = null;
}
}
}
return list;
}
}
/**
*不使用递归解答,这才是最简单而且高效的方法吧。
*从后往前观察后序遍历后的结果就明白思路了。
*/
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if (root == null) return list;
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
list.add(0, node.val);//每次插入到头部
if (node.left != null) stack.push(node.left);
if (node.right != null) stack.push(node.right);
}
return list;
}
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
//=====================递归=================================
class Solution {
public:
void postOrder(TreeNode *root,vector<int>&vec){
if(root != NULL){
postOrder(root->left,vec);
postOrder(root->right,vec);
vec.push_back(root->val);
}
}
vector<int> postorderTraversal(TreeNode *root) {
vector<int>vec;
postOrder(root,vec);
return vec;
}
};
//=====================非递归============================
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int>vec;
if(root == NULL)
return vec;
stack<TreeNode*>st;
st.push(root);
TreeNode * cur = NULL;
while(!st.empty()){
cur = st.top();
if(cur->left == NULL && cur->right == NULL){
vec.push_back(cur->val);
st.pop();
}else{
if(cur->right){
st.push(cur->right);
cur->right = NULL;
}
if(cur->left){
st.push(cur->left);
cur->left = NULL;
}
}
}
return vec;
}
};
import java.util.*;
public class Solution {
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode pre = null;
while (root != null || ! stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.peek();
if(root.right == null || root.right == pre) {
list.add(stack.pop().val);
pre = root;
root = null;
} else root = root.right;
}
return list;
}
}
//思路:用栈来实现,顶点先入栈,向左到最左下角,保存路径,右不为空,右进站继续左
//当左右子树都为空时,访问,弹栈,并将pre到p的指针为0,避免下次再访问该路径。
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
vector<TreeNode *> s;
if (!root)
return res;
s.push_back(root);
TreeNode* p = nullptr;
while (!s.empty()){
p = s.back();
while (p->left){
s.push_back(p->left);
p = p->left;
}
if (p->right == nullptr){
res.push_back(p->val);
s.pop_back();
if(s.empty()) break;//一定要判断
TreeNode *pre = s.back();
if (p == pre->left)
pre->left = nullptr;
if (p == pre->right)
pre->right = nullptr;
}
else
s.push_back(p->right);
}
return res;
}
};
import java.util.*;
public class Solution {
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if(root==null)
return list;
Stack<TreeNode> stack = new Stack<TreeNode>();
Stack<TreeNode> stack2 = new Stack<TreeNode>();
stack.add(root);
while(!stack.isEmpty()){
TreeNode r = stack.pop();
if(r.left!=null)
stack.add(r.left);
if(r.right!=null)
stack.add(r.right);
stack2.add(r);
}
while(!stack2.isEmpty()){
list.add(stack2.pop().val);
}
//LRD(list,root);递归
return list;
}
public void LRD(ArrayList<Integer> list,TreeNode root){
if(root==null)
return;
LRD(list,root.left);
LRD(list,root.right);
list.add(root.val);
}
}
import java.util.ArrayList;
public class Solution {
public ArrayList<integer> postorderTraversal(TreeNode root) {
if (root != null) {
ArrayList<integer> l = postorderTraversal(root.left);
ArrayList<integer> r = postorderTraversal(root.right);
ArrayList<integer> res = new ArrayList<>();
res.addAll(l);
res.addAll(r);
res.add(root.val);
return res;
}
return new ArrayList<>();
}
}
</integer></integer></integer></integer> Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree{1,#,2,3},
1
\
2
/
3return[3,2,1].
Note: Recursive solution is trivial, could you do it iteratively?
就是二叉树的后序遍历,它的意思是,递归程序没啥意思,要不你用非递归来实现一个?
我们知道,递归就是系统栈实现的,那么其实对于本题,我倾向于自己用一个栈来模拟系统栈,这样,无论是前序中序还是后序,改代码跟递归版本是一样,具有较强的通用性,至于另外的解法,每种都不一样,导致不好记忆。
import java.util.*;
class Command{
public String str;
public TreeNode node;
public Command(String str,TreeNode node){
this.str = str;
this.node = node;
}
}
public class Solution {
public ArrayList postorderTraversal(TreeNode root) {
ArrayList res = new ArrayList();
if(root == null){
return res;
}
Stack stack = new Stack();
//遇到“go”则添加左右孩子以及自己入栈
//遇到“print”则添加进结果集
stack.push(new Command("go",root));
while(!stack.isEmpty()){
Command c = stack.pop();
if(c.str == "go"){
//先自己
stack.push(new Command("print",c.node));
//再右
if(c.node.right != null){
stack.push(new Command("go",c.node.right));
}
//再左
if(c.node.left != null){
stack.push(new Command("go",c.node.left));
}
//出栈的顺序必然是左-右-中,即后序遍历顺序
}else{
res.add(c.node.val);
}
}
return res;
}
}我们要想改成前序或者中序遍历,只需要将stack.push(new Command("print",c.node));调换一下位置即可,十分方便,这样对递归的实现原理的理解也加深了。
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> ret = new ArrayList<Integer>();
if(root == null) return null;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root , lastVisitNode = null;
while(cur != null){
stack.add(cur);
cur = cur.left;
}
while(!stack.empty()){
cur = stack.peek();
if(cur.right == null || cur.right == lastVisitNode){
//当右侧节点为空 或者为访问过的节点的时候
stack.pop();
ret.add(cur.val);
lastVisitNode = cur;
}
else{ //节点不为空 且 上次访问的是左树
cur = cur.right;
while(cur != null){
stack.add(cur);
cur = cur.left;
}
}
}
return ret;
}
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> result;
if(root == NULL)
return result;
stack<TreeNode *> s;
s.push(root);
while(!s.empty())
{
TreeNode *p = s.top();
s.pop();
result.push_back(p->val);
if(p->left != NULL)
s.push(p->left);
if(p->right != NULL)
s.push(p->right);
}
reverse(result.begin(), result.end());
return result;
}
}; //大家好,我是yishuihan
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> vec;
if(root==NULL) return vec;
helper(vec,root);
return vec;
}
void helper(vector<int>& vec,TreeNode* root)
{
if(root==NULL) return;
helper(vec,root->left);
helper(vec,root->right);
vec.push_back(root->val);
}
};
import java.util.ArrayList;
public class Solution {
// 后序遍历:左 右 中
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if(root == null) return list;
list.addAll(postorderTraversal(root.left));
list.addAll(postorderTraversal(root.right));
list.add(root.val);
return list;
}
}
/**
* 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> ans;
if (root == NULL) return ans;
vector<TreeNode*> vec;
vec.push_back(root);
while (vec.size() > 0) {
int tail = vec.size() - 1;
if (vec[tail]->left == NULL && vec[tail]->right == NULL) {
ans.push_back(vec[tail]->val);
vec.pop_back();
}
if (vec[tail]->right != NULL) {
vec.push_back(vec[tail]->right);
vec[tail]->right = NULL;
}
if (vec[tail]->left != NULL) {
vec.push_back(vec[tail]->left);
vec[tail]->left = NULL;
}
}
return ans;
}
}; /**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @return int整型vector
*/
vector<int> postorderTraversal(TreeNode* root) {
// write code here
vector<int> ans;
if(!root) return ans;
stack<TreeNode*> buffer;
buffer.push(root);
while(!buffer.empty()){
auto *cur = buffer.top();
if(!cur->left && !cur->right) ans.emplace_back(cur->val), buffer.pop();
else{
if(cur->right) buffer.push(cur->right), cur->right = nullptr;
if(cur->left) buffer.push(cur->left), cur->left = nullptr;
}
}
return ans;
}
}; 1.定义一个辅助栈
2.根节点先入栈
3.左节点入栈
4.栈顶左节点出栈。下一次while内循环的时候左节点的右子树入栈。
vector<int> preorderTraversal(TreeNode *root){
vector<int> res;
if(!root) return res;
stack<TreeNode*> stk;
while(stk.size() > 0 || root != nullptr){
while(root){
//根节点入栈
stk.push(root);
res.push_back(root->val);
//左节点入栈
root = root->left;
}
//保存当前栈顶的right节点。下一次进入第二层又循环的时候入站(相当于右接待你入栈)
root = stk.top()->right;
//左节点出站
stk.pop();
}
return res;
}
vector<int> postorderTraverse(TreeNode* root){
vector<int> res;
if(!root) return res;
stack<TreeNode*> stk;
while(stk.size() > 0 || !root){
while(root){
stk.push(root);
res.push_back(root->val);
//和前序遍历的区别1
root = root->right;
}
//和前序遍历的区别2
root = stk.top()->left;
stk.pop();
}
//和前序遍历的区别3.
reverse(res.begin(), res.end());
return res;
} vector<int> inorderTraverse(TreeNode* root){
vector<int> res;
if(!root) return root;
stack<TreeNode* > stk;
while(stk.size()>0 || !root){
while(root){
stk.push(root);
root = root->left;
}
res.push_back(stk.top()-> val);
//和前序遍历的唯一区别
root = stk.top()->right;
stk.pop();
}
return res;
} import java.util.*;
public class Solution {
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<>();
if(root == null) return list;
Stack<TreeNode> stack = new Stack<>();
Set<TreeNode> set = new HashSet<>();
set.add(root);
stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.pop();
if(set.contains(node.left) && set.contains(node.right)){
list.add(node.val);
continue;
}
set.add(node.right);
set.add(node.left);
stack.push(node);
if(node.right!=null) stack.push(node.right);
if(node.left!=null) stack.push(node.left);
}
return list;
}
} /** 采用 根——右——左 的顺序进行遍历,利用栈实现
遍历过程中将元素值添加到指定ArrayList中
最后将列表翻转即可,间接实现对 左——右——根 的访问
*/
public class Solution {
public ArrayList<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stack=new Stack<TreeNode>();
ArrayList<Integer> list=new ArrayList<Integer>();
if(root!=null){
stack.push(root);
while(stack!=null && stack.size()!=0){
TreeNode p=stack.pop();
list.add(p.val);
if(p.left!=null){
stack.push(p.left);
}
if(p.right!=null){
stack.push(p.right);
}
}
Collections.reverse(list);
}
return list;
}
} /**
* 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) {
if (root==nullptr)
return res;
stack<TreeNode*> s;
s.push(root);
map<TreeNode*,int> flag;
while (!s.empty())
{
TreeNode *temp = s.top();
if (flag[temp]==1)
{
res.push_back(temp->val);
s.pop();
continue;
}
if (temp->right!=nullptr || temp->left!=nullptr)
{
if (temp->right!=nullptr)
{
s.push(temp->right);
flag[temp] = 1;
}
if (temp->left!=nullptr)
{
s.push(temp->left);
flag[temp] = 1;
}
}
else{
res.push_back(temp->val);
s.pop();
}
}
return res;
}
private:
vector<int> res;
};
结合map判断节点是否被访问过 class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if(root==nullptr)
return res;
stack<TreeNode *> stackNode;
TreeNode * leftNode=root;
while(leftNode!=nullptr)
{
stackNode.push(leftNode);
TreeNode * temp=leftNode;
leftNode=leftNode->left;
temp->left=nullptr;
}
while(!stackNode.empty())
{
TreeNode *p=stackNode.top();
if(p->right!=nullptr)
{
TreeNode * q=p->right;
p->right=nullptr;
while(q!=nullptr)
{
stackNode.push(q);
TreeNode * temp=q;
q=q->left;
temp->left=nullptr;
}
}else{
res.push_back(p->val);
stackNode.pop();
}
}
return res;
}
}; import java.util.*;
public class Solution {
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> res = new ArrayList<Integer>();
if (null == root) {
return res;
}
Stack<Integer> reverseRes = new Stack<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode temp = stack.pop();
reverseRes.push(temp.val);
if (null != temp.left) {
stack.push(temp.left);
}
if (null != temp.right) {
stack.push(temp.right);
}
}
while (!reverseRes.isEmpty()) {
res.add(reverseRes.pop());
}
return res;
}
}