力扣二叉树专题(一)介绍了二叉树的深度优先遍历,前中后序的递归、迭代、统一迭代实现。
力扣二叉树专题(二)介绍了二叉树的广度优先遍历中的层序遍历,从左到右一层一层的去遍历二叉树。
对于二叉树的遍历总共8种:
N叉树的前后序遍历和翻转二叉树还是用层序遍历,每道题都用了DFS、BFS
可以参考二叉树的前序遍历和后序遍历的迭代法和递归法的实现
递归法: 要注意的是,遍历子树时,从左边开始,即子节点的第一个开始
class Solution {
public:
//1.递归法
void order(Node* cur, vector<int>& result)
{
if(cur==NULL) return;
result.push_back(cur->val);
for(int i=0;i<cur->children.size();i++)
{
if(cur->children[i]) order(cur->children[i], result);
}
}
vector<int> preorder(Node* root) {
vector<int> result;
order(root, result);//depth可以不传 没啥用
return result;
}
};
迭代法: 用栈访问节点
注意:
class Solution {
public:
//迭代法
vector<int> preorder(Node* root)
{
vector<int> result;
stack<Node*> st;
if(root==NULL) return result;
//根节点
st.push(root);
while(!st.empty())
{
Node* cur = st.top();
st.pop();
result.push_back(cur->val);
for(int i=0;i<cur->children.size();i++)
{
//从后面开始存 栈先进后出
if(cur->children[cur->children.size()-1-i]) st.push(cur->children[cur->children.size()-1-i]);
}
}
return result;
}
};
在前序遍历的基础上调整一下代码顺序
递归法: 中右左顺序递归,最后反转一下数组
class Solution {
public:
//递归法
void order(Node* cur, vector<int>& result)
{
if(!cur) return;
result.push_back(cur->val);
for(int i=0;i<cur->children.size();i++)
{
order(cur->children[cur->children.size() - 1 - i], result);//中右左
}
}
vector<int> postorder(Node* root) {
vector<int> result;
order(root, result);
reverse(result.begin(), result.end());
return result;
}
};
迭代法: 入栈时,中右左顺序,最后反转一下数组
class Solution {
public:
//迭代法
vector<int> postorder(Node* root)
{
vector<int> result;
stack<Node*> st;
if(!root) return result;//空树
st.push(root);//根节点先处理
while(!st.empty())
{
Node* cur = st.top();
st.pop();
result.push_back(cur->val);
for(int i=0; i<cur->children.size(); i++)
{
if(cur->children[i]) st.push(cur->children[i]);
}
}
reverse(result.begin(), result.end());
return result;
}
};
DFS 前序遍历-递归法 确定三个条件(参数及返回值;递归结束条件;递归单次操作)
首先,判断节点是否为空,为空则空树或是遍历结束;
然后,如果节点有子节点(只有左子节点、只有右子节点、有左右节点)都进行交换;
最后,递归,分别传入节点的左右子节点
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;
}
};
DFS的中序和后序的递归实现把上面的代码调整一下顺序就好了
DFS 前序遍历-迭代法 栈
class Solution {
public:
//DFS 前序遍历-迭代法 栈
TreeNode* invertTree(TreeNode* root)
{
stack<TreeNode*> st;
if(root) st.push(root);
while(!st.empty())
{
TreeNode* cur = st.top();//中
st.pop();
swap(cur->left, cur->right);
if(cur->left) st.push(cur->left);//左
if(cur->right) st.push(cur->right);//右
}
return root;
}
};
DFS 后序遍历-迭代法 栈
class Solution {
public:
//DFS 后序遍历-迭代法 栈
TreeNode* invertTree(TreeNode* root)
{
stack<TreeNode*> st;
if(root) st.push(root);
while(!st.empty())
{
TreeNode* cur = st.top();//中
st.pop();
swap(cur->left, cur->right);
if(cur->right) st.push(cur->right);//右
if(cur->left) st.push(cur->left);//左
}
return root;
}
};
DFS 中序遍历-统一迭代法 栈 中节点要标记 先访问再处理
class Solution {
public:
//DFS 中序遍历-统一迭代法 栈
TreeNode* invertTree(TreeNode* root)
{
stack<TreeNode*> st;
if(root) st.push(root);
while(!st.empty())
{
TreeNode* cur = st.top();
if(cur)//先访问节点
{
st.pop();
if(cur->right) st.push(cur->right);//右
st.push(cur);///中
st.push(NULL);//标记
if(cur->left) st.push(cur->left);//左;
}
else//再处理节点
{
st.pop();//弹出空节点
cur = st.top();//处理空节点的下一个节点
st.pop();
swap(cur->left, cur->right);
}
}
return root;
}
};
BFS 层序遍历-迭代法 队列
class Solution {
public:
//迭代法
TreeNode* invertTree(TreeNode* root)
{
queue<TreeNode*> que;
if(root) que.push(root);
while(!que.empty())
{
TreeNode* cur = que.front();
que.pop();
swap(cur->left, cur->right);//中
if(cur->left) que.push(cur->left);//左
if(cur->right) que.push(cur->right);//右
}
return root;
}
};
总结