迭代遍历:
前序遍历(中,左,右)
使用栈需要注意,栈要先插入右,左才能弹出左右
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode* > sta;
sta.push(root);
vector<int> res;
if(root == nullptr) return res;
while(!sta.empty())
{
TreeNode* node = sta.top();
sta.pop();
res.push_back(node->val);
if(node->right) sta.push(node->right);
if(node->left) sta.push(node->left);
}
return res;
}
};
中序遍历(左,中,右)
需要先把左子树的所有节点从左至右遍历,最后遍历中节点和右节点
代码:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
TreeNode* node = root;
vector<int> res;
stack<TreeNode* > sta;
while(!sta.empty() || node != nullptr)
{
if(node != nullptr)
{
sta.push(node);
node = node->left;
}
else
{
node = sta.top();
sta.pop();
res.push_back(node->val);
node = node->right;
}
}
return res;
}
};
后序遍历(左,右,中)
主要注意,后序遍历可以在前序遍历基础上更改为正常的中,左,右插入,最后再反转res,就能得到左,右,中的顺序
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode* > sta;
vector<int> res;
sta.push(root);
if(root == nullptr) return res;
while(!sta.empty())
{
TreeNode* node = sta.top();
sta.pop();
res.push_back(node->val);
if(node->left) sta.push(node->left);
if(node->right) sta.push(node->right);
}
reverse(res.begin(),res.end());
return res;
}
};
思路:翻转整个二叉树只需要把每个子树翻转,即将每个节点的左右孩子翻转,就可以达到翻转整个二叉树
代码:
层序遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
queue<TreeNode*> que;
que.push(root);
if(root == nullptr) return root;
while(!que.empty())
{
int n = que.size();
for(int i = 0;i < n;i++)
{
TreeNode* node = que.front();
que.pop();
swap(node->left,node->right);
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return root;
}
};
递归遍历:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root == nullptr) return root;
swap(root->left,root->right);
invertTree(root->left);
invertTree(root->right);
return root;
}
};
思路:需要翻转整个左右子树,然后分别判断内子树和外子树的值是否相同,可以用栈或者队列存储每层的节点
代码:
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(root == nullptr) return true;
stack<TreeNode* > sta;
sta.push(root->left);
sta.push(root->right);//先把root的左右子节点加入
while(!sta.empty())
{
TreeNode* rightnode = sta.top();//对应的第一个弹出的就是就是右节点
sta.pop();
TreeNode* leftnode = sta.top();
sta.pop();
if(leftnode == nullptr && rightnode == nullptr) continue;//如果遇到有一层的左节点没有右子节点并且右节点没有左子结点,就继续下一层节点的遍历
if(leftnode == nullptr || rightnode == nullptr || leftnode->val != rightnode->val) return false;
sta.push(leftnode->left);
sta.push(rightnode->right);对比双方是对称的两个节点
sta.push(leftnode->right);
sta.push(rightnode->left);
}
return true;
}
};
思路:层序遍历,每进入新的一层深度加1
代码:
class Solution {
public:
int maxDepth(TreeNode* root) {
queue<TreeNode* > que;
que.push(root);
int depth = 0;
if(root == nullptr) return depth;
while(!que.empty())
{
int n = que.size();
depth++;
for(int i = 0;i < n;i++)
{
TreeNode* node = que.front();
que.pop();
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return depth;
}
};
代码:
class Solution {
public:
int maxDepth(Node* root) {
queue<Node* > que;
que.push(root);
int depth = 0;
if(root == nullptr) return depth;
while(!que.empty())
{
int n = que.size();
depth++;
vector<int> vec;
for(int i = 0;i < n;i++)
{
Node* node = que.front();
que.pop();
for(auto children : node->children)
{
if(children != nullptr)
{
que.push(children);
}
}
}
}
return depth;
}
};
思路:和求二叉树的最大深度类似,通过层数判断深度,往下遍历时,最先找到的叶子结点一定是深度最小的节点
代码:
class Solution {
public:
int minDepth(TreeNode* root) {
queue<TreeNode*> que;
que.push(root);
int depth = 0;
if(root == nullptr) return depth;
while(!que.empty())
{
depth++;
int n = que.size();
for(int i = 0; i < n; i++)
{
TreeNode* node = que.front();
que.pop();
if(node->left == nullptr && node->right == nullptr) return depth;//最先找到的叶子结点一定是深度最小的节点
if(node->left) que.push(node->left);
if(node->right) que.push(node->right);
}
}
return depth;
}
};