【LeetCode】Binary Tree Postorder Traversal

本文详细解释了后序遍历二叉树的递归与非递归方法,包括思路、代码实现及优化技巧。重点介绍了非递归方法中的堆栈应用,并提供了示例代码。此外,还讨论了如何在代码中正确使用`vector`进行数据拼接,以及推荐了学习C++的相关资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考链接:

参考1:在写非递归时遇到一点困难,一直没想明白应该怎么写,最后参加这个代码终于写出来的。

http://www.cnblogs.com/changchengxiao/p/3416402.html

谢谢分享!

参考2:这个方法很有意思,利用堆栈很按后序的逆序输入再做一次逆序,赞!!!

http://www.cnblogs.com/xinsheng/p/3460480.html

题目描述


[LeetCode] 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?

题目分析

递归方法:
这个方法简单,只要按照 左儿子 -> 右儿子 -> 自己 的顺序就可以了

非递归方法1:
相比于前序遍历,后续遍历思维上难度要大些,前序遍历是通过一个stack,首先压入父亲结点,然后弹出父亲结点,并输出它的value,之后压人其右儿子,左儿子即可。然而后序遍历结点的访问顺序是:左儿子 -> 右儿子 -> 自己。那么一个结点需要两种情况下才能够输出:第一,它已经是叶子结点;第二,它不是叶子结点,但是它的儿子已经输出过(代码里非递归方法head就是用来记录访问过的儿子的)。那么基于此我们只需要记录一下当前输出的结点即可。对于一个新的结点,如果它不是叶子结点,儿子也没有访问,那么就需要将它的右儿子,左儿子压入。如果它满足输出条件,则输出它,并记录下当前输出结点。输出在stack为空时结束。


非递归方法2:

利用堆栈很按后序的逆序输入再做一次逆序

从一开始,就按 自己->右儿子->左儿子顺序输出,最后做一下逆序就好

总结

在写代码时有一个地方出了bug,有的是就是没搞明白怎么把两个vector拼在一起

这里对vector的使用方法要得当,把两个vector拼在一起的方法:
把out1,out2,拼成(out1,out2) 
out2.insert(out2.begin(),out1.begin(),out1.end());//out1,out2顺序不要弄错 


示例代码

/*
编译环境CFree 5.0 
*/
#include 
  
   
#include 
   
    
#include 
    
     
using namespace std;


#define METHOD 1 //1- 递归法
//#define METHOD 2//2- 堆栈方法1 
//#define METHOD 3//3- 堆栈方法3 


 

/**
 * Definition for binary tree
 */
struct TreeNode {
    int val;
     TreeNode *left;
     TreeNode *right;
     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 };
void printVector(vector
     
       in,char* name)
{
	printf("%s size=%d\n",name,in.size());	
	for(int i = 0;i< in.size();i++)
    {
    	printf("%d  ",in[i]);
	}
	printf("\n");
}
#if METHOD == 1
/*
这里对vector的使用方法要得当,把两个vector拼在一起的方法是
把out1,out2,拼成(out1,out2) 
out2.insert(out2.begin(),out1.begin(),out1.end());//out1,out2顺序不要弄错 
*/
class Solution {
public:
    vector
      
        postorderTraversal(TreeNode *root) {
        vector
       
         out; if(root == NULL) return out; vector
        
          out1 = postorderTraversal(root->left); vector
         
           out2 = postorderTraversal(root->right); out.insert(out.begin(),root->val); //中 out.insert(out.begin(),out2.begin(),out2.end()); //右 out.insert(out.begin(),out1.begin(),out1.end()); //左 return out; } }; #elif METHOD == 2 //堆栈方法 //这个方法不太好理解,需要加以研究 class Solution { public: vector
          
            postorderTraversal(TreeNode *root) { vector
           
             out; if(root == NULL) return out; TreeNode *head = root; //就是记录上一个弹出的结点 treenodeStack.push(root); while(!treenodeStack.empty()) { TreeNode *cur = treenodeStack.top();//增加一个记录点 if(cur->left == head || cur->right== head ||(cur->left == NULL && cur->right == NULL))//这个条件很关键 { treenodeStack.pop(); out.push_back(cur->val); head = cur; //printf("pop = %d\n",cur->val); //system("pause"); } else { if(cur->right != NULL) treenodeStack.push(cur->right)/*,printf("lpush = %d\n",cur->right->val)*/; if(cur->left != NULL) treenodeStack.push(cur->left)/*,printf("rpush = %d\n",cur->left->val)*/; } } return out; } private: stack
            
              treenodeStack; }; #elif METHOD == 3 /* 这个方法赞呀!自己->右儿子->左儿子顺序输出,最后做一下逆序就好 */ class Solution { public: vector
             
               postorderTraversal(TreeNode *root) { vector
              
                res; if(root == NULL) return res; vector
               
                 stc; stc.push_back(root); while(!stc.empty()) { TreeNode* node = stc.back(); res.push_back(node->val); stc.pop_back(); if(node->left != NULL) { stc.push_back(node->left); } if(node->right != NULL) { stc.push_back(node->right); } } reverse(res.begin(), res.end()); return res; } }; #endif /*功能测试*/ void test0() { /* 1 2 3 4 5 6 7 */ TreeNode node1(1); TreeNode node2(2); TreeNode node3(3); TreeNode node4(4); TreeNode node5(5); TreeNode node6(6); TreeNode node7(7); node1.left = &node2; node1.right = &node3; node2.left = &node4; node2.right = &node5; node3.left = &node6; node3.right = &node7; Solution so; vector
                
                  out = so.postorderTraversal(&node1); int tmp[7] = {4,5,2,6,7,3,1}; int i = 0; for(i = 0;i<7 && i
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
   
  

推荐学习C++的资料

C++标准函数库
在线C++API查询

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值