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?
递归
/**
* 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> res;
vector<int> postorderTraversal(TreeNode *root) {
if (root == NULL) {
return res;
}
postorderTraversal(root->left);
postorderTraversal(root->right);
res.push_back(root->val);
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> res;
stack<int> nodeState;
stack<TreeNode*> node;
if (root == NULL) {
return res;
}
node.push(root);
nodeState.push(0);
while (!node.empty()) {
auto n = node.top();
node.pop();
auto state = nodeState.top();
nodeState.pop();
if (state == 0) {
node.push(n);
nodeState.push(1);
if (n->right) {
node.push(n->right);
nodeState.push(0);
}
if (n->left) {
node.push(n->left);
nodeState.push(0);
}
} else {
res.push_back(n->val);
}
}
return res;
}
};Morris遍历
基本思想和先序和中序遍历一样,但是要麻烦一些。只是在遍历前,增加了一个类似头节点的节点作为整个遍历过程的起始节点。由于后序遍历先访问左子树,然后是右子树,最后访问根节点,所以在Morris算法遍历过程中,增加一个头节点dump表示新二叉树的根节点,让这个新的根节点的左指针指向原二叉树的根节点,右指针为NULL。对于某个节点N,先遍历N的左子树的左子树,再逆序遍历从N节点的左子树的根节点到中序遍历过程访问的最右节点这条路径上的节点。
/**
* 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> res;
vector<int> postorderTraversal(TreeNode *root) {
if (root == NULL) {
return res;
}
TreeNode *dummy = new TreeNode(-1);
dummy->left = root;
TreeNode *p = dummy;
while (p) {
if (!p->left) {
p = p->right;
} else {
auto tmp = p->left;
while (tmp->right && tmp->right != p) {
tmp = tmp->right;
}
if (!tmp->right) {
tmp->right = p;
p = p->left;
} else {
pustres(p->left, tmp);
tmp->right = NULL;
p = p->right;
}
}
}
return res;
}
//同反转单链表
void reverse(TreeNode *begin, TreeNode *end) {
if (begin == end) {
return ;
}
TreeNode *prev = begin;
TreeNode *cur = begin->right;
TreeNode *next = cur?cur->right:NULL;
while (prev != end) {
cur->right = prev;
prev = cur;
cur = next;
next = next?next->right:NULL;
}
}
void pustres(TreeNode *begin, TreeNode *end) {
TreeNode *p;
reverse(begin, end);
p = end;
while (true) {
res.push_back(p->val);
if (p == begin) {
break;
}
p = p->right;
}
reverse(end, begin);
}
};
本文介绍二叉树后序遍历的三种方法:递归、栈迭代及Morris遍历。递归方法简洁但栈使用较多;迭代法利用栈实现非递归遍历;Morris遍历则在不额外使用栈的基础上完成遍历。
318

被折叠的 条评论
为什么被折叠?



