二叉树先序遍历的两种方法

文章详细介绍了在LeetCode中使用递归和非递归方法实现二叉树的前序遍历,包括递归的逻辑和非递归(利用栈)的步骤,分析了时间复杂度和空间复杂度。
摘要由CSDN通过智能技术生成

144. 二叉树的前序遍历 - 力扣(LeetCode)

方法一: 用递归实现先序遍历的方法

由先序遍历的方式及其规律可知:先访问根节点再遍历左子树,最后访问右子树。

其规律不知道的需要翻阅一下教材,故编写代码的时候可以应用此规律。

我们需要了解什么是二叉树的前序遍历:按照访问根节点——左子树——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。因此整个遍历过程天然具有递归的性质,我们可以直接用递归函数来模拟这一过程.

定义 preorder(head) 表示当前遍历到 head节点的答案。按照定义,我们只要首先将head节点的值加入答案,然后递归调用 preorder(head.left) 来遍历head节点的左子树,最后递归调用 preorder(head.right) 来遍历 head 节点的右子树即可,递归终止的条件为碰到空节点。

复杂度分析

时间复杂度:O(n),其中 n是二叉树的节点数。每一个节点恰好被遍历一次。

空间复杂度:O(n),为递归过程中栈的开销,平均情况下为 O(log⁡n),最坏情况下树呈现链状,为 O(n)。

代码如下

. - 力扣(LeetCode)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:

     /* void inorder(TreeNode* head,vector<int>& a)
{
    if(head==nullptr){
        return ;
    }
    a.push_back(head->val);
    inorder(head->left,a);
    inorder(head->right,a);
}*/
       void preorder(TreeNode* head,vector<int>&a){
        if(head==nullptr){
            return;//先访问根节点
        }
        a.push_back(head->val);
        if(head->left){//若有左子树,则访问左子树
            preorder(head->left,a);
        }
        if(head->right){//若有右子树,则访问右子树
            preorder(head->right,a);
        }
       }
    vector<int> preorderTraversal(TreeNode* head) {
         vector<int>a;
       preorder(head,a);
       return a;
    }
};

 方法二:用栈实现(非递归方式)先序遍历

具体步骤:

栈实现非递归遍历的思路如下:

1.定义一个栈s,将根节点压入栈。

2.若栈不为空,则将栈顶压入结果数组ans,同时弹出栈顶。

3.若栈顶节点的右子树存在,则压入该节点入栈,

若栈顶节点的左子树存在,则将其压入栈,

这样做的方式是左子树在右子树的上方,待其弹出是也是先左后右。

4.重复操作,最终返回结果

复杂度分析

时间复杂度:O(n),其中 n 是二叉树的节点数。每一个节点恰好被遍历一次。

空间复杂度:O(n),为迭代过程中显式栈的开销,平均情况下为 O(log⁡n),最坏情况下树呈现链状,为 O(n)。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:

     /* void inorder(TreeNode* head,vector<int>& a)
{
    if(head==nullptr){
        return ;
    }
    a.push_back(head->val);
    inorder(head->left,a);
    inorder(head->right,a);
}*/
    vector<int> preorderTraversal(TreeNode* head) {
         vector<int>ans;
         if(head==nullptr){
            return ans;
         }
 stack<TreeNode*>s;
     s.push(head);
     while(s.size()){
        auto node=s.top();
        ans.push_back(node->val);
        s.pop();
        if(node->right){
            s.push(node->right);
        }
        if(node->left){
            s.push(node->left);
        }
       } 
       return ans;
    
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值