代码随想录算法训练营第十四天|144.二叉树的前序遍历、94.二叉树的中序遍历、145.二叉树的后序遍历

本文详细介绍了二叉树的基本结构,包括术语解释、节点度和层次,以及前序、中序和后序遍历的递归和迭代实现方法。通过实例展示了如何使用栈来模拟递归过程,实现高效的遍历算法。
摘要由CSDN通过智能技术生成

文档讲解
二叉树 栈

二叉树结构

struct TreeNode
{
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x):val(x),left(nullptr),right(nullptr){}
};

二叉树常用术语

  • 根节点 root node:位于二叉树顶层的节点,没有父节点
  • 叶节点 leaf node:没有子节点的节点,其两个指针均指向None。
  • 边 edge:连接两个节点的线段,即节点引用(指针)。
  • 节点所在层level:从顶到底递增,根节点所在层为1。
  • 节点的度degree:节点的子节点的数量。在二叉树中,度的取值范围是0、1、2。
  • 二叉树的高度height:从根节点到最远节点所经过的边的数量。
  • 节点的深度depth:从根节点到该节点所经过的边的数量。
  • 节点的高度height:从距离该节点最远的叶节点到该节点所经过的边的数量。

二叉树的类型

  • 完美二叉树(满二叉树)

    在满二叉树中,叶子节点的度为0,其余所有节点的度都为2;若树高度为h,节点总数为 2 h + 1 − 1 2^{h+1}-1 2h+11

  • 完全二叉树

    与满二叉树的区分,只有底层的节点没有被填满,且其填满的顺序是从左到右填充。

  • 完满二叉树

    除了叶节点之外,其余所有节点都有两个子节点。

  • 平衡二叉树

    平衡二叉树中左子树和右子树的高度之差的绝对值不超过1。

  • 二叉树的退化

    二叉树的退化:当所有节点都偏向一侧时,二叉树退化为“链表”。

二叉树的遍历

递归遍历:
1.前序遍历
144.二叉树的前序遍历

时间复杂度:O(n)
空间复杂度:O(n)

class Solution {
public:
    void preorder(TreeNode* node,vector<int>& result)
    {
        if(node==nullptr) return;
        result.push_back(node->val);
        preorder(node->left,result);
        preorder(node->right,result);
        
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        preorder(root,result);
        return result;
    }
};

2.中序遍历
94.二叉树的中序遍历

时间复杂度:O(n)
空间复杂度:O(n)

class Solution {
public:
    void inorder(TreeNode* node,vector<int>& result)
    {
        if(node==nullptr)return;
        inorder(node->left,result);
        result.push_back(node->val);
        inorder(node->right,result);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        inorder(root,result);
        return result;
    }
};

3.后序遍历
145.二叉树的后序遍历

时间复杂度:O(n)
空间复杂度:O(n)

class Solution {
public:
    void postorder(TreeNode* node,vector<int>& result)
    {
        if(node==nullptr)return;
        postorder(node->left,result);
        postorder(node->right,result);
        result.push_back(node->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> result;
        postorder(root,result);
        return result;
    }
};

迭代法:

思路:首先我们使用了递归法来完成了三种遍历方法,因为递归的过程就是一个不断使用栈的过程,故我们可以使用栈这种数据结构来存

1.前序遍历

时间复杂度:O(n)
空间复杂度:O(n)

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> stk;
        if(root==nullptr)return result;
        stk.push(root);
        while(!stk.empty())
        {
            TreeNode* node=stk.top();
            stk.pop();
            result.push_back(node->val);
            if(node->right)stk.push(node->right);
            if(node->left)stk.push(node->left);
        }
        return result;
    }
};

2.中序遍历

时间复杂度:O(n)
空间复杂度:O(n)
思路:
在这里插入图片描述
在这里插入图片描述
可以从这个遍历过程看出,对于迭代法写中序遍历而言,每次都应该将这个子树走完。即其作为上一个树的左节点,但是其在下一层又是中间节点。故为什么每次给result添加数据都是中这一步, 每个节点都可以看成中,取决你在哪一层的问题!

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> stk;
        TreeNode* cur=root;
        while(cur!=nullptr||!stk.empty())
        {
            if(cur!=nullptr)
            {
                stk.push(cur);
                cur=cur->left;//左
            }
            else//只有访问到左边的空节点才能进入这里,此时的top(),相当于是中这个位置
            {
                cur=stk.top();//中
                stk.pop();
                result.push_back(cur->val);
                cur=cur->right;//右
            }
        }
        return result;
    }
};

3.后序遍历

时间复杂度:O(n)
空间复杂度:O(n)

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> stk;
        if(root==nullptr)return result;
        stk.push(root);
        while(!stk.empty())
        {
            TreeNode* node=stk.top();
            stk.pop();
            result.push_back(node->val);
            if(node->left)stk.push(node->left);
            if(node->right)stk.push(node->right);
        }
        reverse(result.begin(),result.end());
        return result;
    }
};

二叉树的统一迭代法

时间复杂度:O(n)
空间复杂度:O(n)
在这里插入图片描述
整个过程:1.65null4;2.65null24null1;3.65null24null1null;后面就弹出过程了。

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*> st;
        if(root!=nullptr)st.push(root);
        while(!st.empty())
        {
            TreeNode *node=st.top();
            if(node!=nullptr)
            {
                st.pop();
                if(node->right)st.push(node->right);
                st.push(node);
                st.push(NULL);
                if(node->left)st.push(node->left);
            }
            else
            {
                st.pop();
                node=st.top();
                st.pop();
                result.push_back(node->val);
            }
        }
        return result;
    }
};
  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值