day14二叉树的遍历

文章详细介绍了如何使用递归和栈来实现二叉树的前序、中序和后序遍历。递归方法中,分别说明了在不同位置添加节点值以实现不同遍历顺序。非递归方法中,利用栈进行操作,重点在于控制访问节点的时机,以达到不同的遍历效果。
摘要由CSDN通过智能技术生成

144. 二叉树的前序遍历
94. 二叉树的中序遍历
145. 二叉树的后序遍历

//递归
//确定递归参数和返回值     确定递归出口 确定单层逻辑   
 void dfs(TreeNode* root, vector<int>&result){
        if(!root) return;
        result.push_back(root->val); // 放在这是前序遍历 
        dfs(root->left, result);
        //result.push_back(root->val); // 放在这是中序遍历 
        dfs(root->right, result);
        //result.push_back(root->val); // 放在这是后序遍历 
    }

使用栈模拟递归过程

		//整体流程
      		stack<TreeNode*>s;
            vector<int>reslut;
            while(root||!s.empty()){  
            	if(root不为空){
                  左子节点入栈
            	}else{
            		拿出栈顶元素
            		判断栈顶元素是否出栈
            		当前节点指向栈顶元素的右子节点
            	}
			}

前序和中序遍历都是一次入栈,区别就是访问的时刻,
前序在入栈访问,中序在出栈时访问

//非递归
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
            stack<TreeNode*>s;
            vector<int>reslut;
            while(root||!s.empty()){
                if(root){
                    s.push(root);
                    reslut.push_back(root->val);//前序遍历访问
                    root = root->left;
                }else{
                    TreeNode *node = s.top();
                    // reslut.push_back(node->val); //中序遍历访问
                    s.pop();
                    root = node->right;
                }
            }
            return reslut;
    }
};

后序遍历的访问要求在右子节点访问之后,那么要不要进行出栈就要看以下两个条件

  1. 它的右子节点为空 该节点出栈
  2. 上一次出栈的是它的右子节点,该节点出栈,
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int>result;
        stack<TreeNode*>s;
        TreeNode * pre = nullptr;   // 记录上一个出栈的节点
        while(root || !s.empty()){
            if(root){
                s.push(root);
                root = root->left;   
            }else{
                TreeNode *node = s.top();
                if(!node->right || node->right == pre){//右节点为空或者上一次出栈的是自己的右节点
                    result.push_back(node->val);
                    s.pop();
                    pre = node;
                    root = nullptr;  // 因为出栈,下一个节点还是要从栈里弹出进行判断,所以这里要重新设置以下root
                }else{
                    root =node->right;  //不符合出栈要求那么就将其右节点压栈
                }
            }
        }
        return result;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值