目录
前言
前序遍历:根节点->左子树->右子树(根->左->右)
中序遍历:左子树->根节点->右子树(左->根->右)
后序遍历:左子树->右子树->根节点(左->右->根)
提示:以下代码仅供参考
一、二叉树的遍历
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),为递归过程中栈的开销。