二叉树与N叉树的深度优先遍历(C++)


前言

前序遍历:根节点->左子树->右子树(根->左->右)
中序遍历:左子树->根节点->右子树(左->根->右)
后序遍历:左子树->右子树->根节点(左->右->根)


提示:以下代码仅供参考

一、二叉树的遍历

1.1 前序遍历

题目描述:给定一个二叉树的根节点 root ,返回它的前序遍历。

/**
 * 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:
    vector<int> res;
    void dfs(TreeNode* root){
        if(root==nullptr)//递归结束的终止条件是当前节点为空
        return;
        res.push_back(root->val);
        dfs(root->left);
        dfs(root->right);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        dfs(root);
        return res;
    }
};
1.2 中序遍历

题目描述:给定一个二叉树的根节点 root ,返回它的中序遍历。

/**
 * 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:
    vector<int> res;
    void dfs(TreeNode* root){
        if(root==nullptr)
        return;
        dfs(root->left);
        res.push_back(root->val);
        dfs(root->right);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        dfs(root);
        return res;
    }
};
1.3 后序遍历

题目描述:给定一棵二叉树的根节点 root ,返回其节点值的后序遍历 。

/**
 * 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:
    vector<int> res;
    void dfs(TreeNode* root){
        if(root==nullptr)
        return;
        dfs(root->left);
        dfs(root->right);
        res.push_back(root->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        dfs(root);
        return res;
    }
};
1.4 二叉树的最小深度

题目描述:给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
题目分析:对于每一个非叶子节点,记录其左右子树的最小叶子节点深度,可用递归实现。

/**
 * 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:
    int minDepth(TreeNode* root) {
        if(root==nullptr)  //如果当前节点是空节点,返回深度0
        return 0;  
        else if(root->left==nullptr)  //如果当前节点的左子树为空,右子树的深度+1即为当前节点的深度
        return minDepth(root->right)+1;
        else if(root->right==nullptr)  //如果当前节点的右子树为空,左子树的深度+1即为当前节点的深度
        return minDepth(root->left)+1;
        else return min(minDepth(root->left),minDepth(root->right))+1;  //如果当前节点的左右子树均存在,则左右子树中的最小深度+1即为当前节点的最小深度
    }
};
1.5 二叉树的最大深度

题目描述:给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
题目分析:对于每一个非叶子节点,记录其左右子树最大叶子节点深度,可递归实现。

/**
 * 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:
    int maxDepth(TreeNode* root) {
        if(root==nullptr)  //如果当前节点为空,返回0
        return 0;
        return max(maxDepth(root->left),maxDepth(root->right))+1;  //返回左右子树的最大深度
    }
};
1.6 相同的树

题目描述:给定两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
题目分析:首先判断两棵树的根节点是否都存在。当根节点均存在时,判断根节点的值是否相同。当根节点的值均相同时,递归判断两棵树的左右子树的根节点。

/**
 * 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:
    bool isSameTree(TreeNode* p, TreeNode* q) {
        if(p==nullptr&&q==nullptr)  //如果两颗树的节点均为空,返回真
        return true;
        else if(p==nullptr||q==nullptr)  //如果两颗树中一棵树的节点值为空,返回假
        return false;  //由于前面已经给出了两棵树均为空的情况,所以p==nullptr||q==nullptr表示只有一棵树为空
        else if(p->val!=q->val) //表示两棵树节点均存在,但节点值不相等
        return false;
        return isSameTree(p->left,q->left)&&isSameTree(p->right,q->right);
    }
};
1.7 对称二叉树

题目描述:给定一个二叉树的根节点 root , 检查它是否轴对称。
题目分析:一棵树是轴对称的,并不是其左右孩子节点对称,而是其左右子树轴对称。因此,在深度遍历时,递归函数用于判断左右子树是否轴对称,即两棵树是否轴对称。

/**
 * 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:
    bool dfs(TreeNode* left,TreeNode* right){
        if(left==nullptr&&right==nullptr)  //左子树和右子树均为空,返回真
        return true;
        if(left==nullptr||right==nullptr)  //左子树为空或右子树为空,返回假
        return false;
        if(left->val!=right->val)  //左右子树均存在,但根节点值不同,返回假
        return false;
        return dfs(left->left,right->right)&&dfs(left->right,right->left);  //左右子树根节点值相同
    }
    bool isSymmetric(TreeNode* root) {
        if(root==nullptr)  //根节点为空 
        return true;
        return dfs(root->left,root->right);
    }
};
1.7 平衡二叉树

题目描述:给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过 1 。
题目分析:对于当前节点,判断该节点的左右子树的左右子树的高度差是否超过1,再判断以当前节点为根的左右子树的高度差是否超过1。不断向上递归。

/**
 * 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:
    int Height(TreeNode* root){
        if(root==nullptr)
        return 0;
        int leftHeight=Height(root->left);  //计算左子树的深度
        int rightHeight=Height(root->right);  //计算右子树的深度
        if(leftHeight==-1||rightHeight==-1||abs(rightHeight-leftHeight)>1)
        return -1;  //如果左右子树的深度差大于1,则返回-1
        return max(leftHeight,rightHeight)+1;
    }
    bool isBalanced(TreeNode* root) {
        return Height(root)>=0;
    }
};

二、N叉树的遍历

2.1 前序遍历

题目描述:给定一个n叉树的根节点 root ,返回其节点值的前序遍历 。

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;
    Node() {}
    Node(int _val) {
        val = _val;
    }
    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<int> res;
    void dfs(Node* root){
        if(root==nullptr)
        return;  //递归终止的条件是当前节点为空
        res.push_back(root->val);
        for(int i=0;i<root->children.size();i++){
            dfs(root->children[i]);
        }
    }
    vector<int> preorder(Node* root) {
        dfs(root);
        return res;
    }
};
2.2 后序遍历

题目描述:给定一个n叉树的根节点 root ,返回其节点值的后序遍历 。

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;
    Node() {}
    Node(int _val) {
        val = _val;
    }
    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<int> res;
    void dfs(Node* root){
        if(root==nullptr)
        return;
        for(int i=0;i<root->children.size();i++){
            dfs(root->children[i]);
        }
        res.push_back(root->val);
    }
    vector<int> postorder(Node* root) {
        dfs(root);
        return res;
    }
};
2.3 N叉树的最大深度

题目描述:给定一个 N 叉树,找到其最大深度。最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
题目分析:对于每个非叶子节点,记录其所有子树中的最大深度值,用递归来实现。

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;
    Node() {}
    Node(int _val) {
        val = _val;
    }
    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    int maxDepth(Node* root) {
        if(root==nullptr)  //如果当前节点为空,返回深度值0;
        return 0;
        int tmp=0;
        for(auto child:root->children){
            tmp=max(maxDepth(child),tmp);  //对于每个节点的孩子节点,寻找到其孩子节点中的最大深度
        }
        return tmp+1;
    }
};

总结

二叉树的前中后序遍历和N叉树的前后序遍历均采用递归实现。其时间复杂度为O(n),其中 n 是二叉树或N叉树的节点数,每一个节点恰好被遍历一次。空间复杂度为O(n),为递归过程中栈的开销。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值