Givena binary tree, return the postorder traversal of its nodes' values.
后续遍历二叉树。
递归思想:前遍历左子树,再遍历右子树,最后显示自身的值。
代码如下:
void postorder(TreeNode *root)
{
if(root != NULL)
{
postorder(root->left,arr);
postorder(root->right,arr);
std::cout<<root->val<<” “;
}
}
非递归算法:借鉴于递归思想,后序遍历必须先遍历某个结点的左子树,再遍历其右子树。所以需要一个状态去表明某个结点,其左右子树是否全部已经遍历完,只有左右子树都遍历完了,才轮到自身。并且需要栈保存自身结点信息,在遍历完左子树,还需要退回再遍历右子树。因此非递归需要用到栈。
具体代码如下:
struct stkNode
{
TreeNode* ptr;
bool tag;
stkNode(TreeNode* p = NULL):ptr(p){}
};
vector<int> postorderTraversal(TreeNode *root)
{
vector<int> arr;
stack< stkNode > S;
stkNode w;
TreeNode* p = root;
do{
while(p!=NULL)
{
w.ptr = p;
w.tag = false;
S.push(w);
p = p->left;
}
int con = 1;
while(con && !S.empty())
{
w = S.top();
p = w.ptr;
S.pop();
switch(w.tag)
{
case false: w.tag = true;
S.push(w);
p = p->right;
con = 0;
break;
case true: arr.push_back(p->val);break;
}
}
}while(!S.empty());
return arr;
}
还有一种比较巧妙的解法,或许遍历是左、右、根,反过来是根、右、左。而前序遍历是根、左、右。那么只需按照前序遍历的算法,稍微不同的是由根、左、右改为根、右、左。然后再reverse以下,就是后续遍历了。
算法如下:
vector<int> postorderTraversal(TreeNode *root) {
stack<TreeNode *> node_stack;
vector<int> res;
if(root!=NULL)
{
node_stack.push(root);
while(!node_stack.empty())
{
TreeNode *temp = node_stack.top();
node_stack.pop();
res.push_back(temp->val);
if(temp->left)
node_stack.push(temp->left);
if(temp- >right)
node_stack.push(temp->right);
}
reverse(res.begin(),res.end());
}
return res;
}