二叉树遍历
树的遍历:
前序遍历
问题描述:
思路:
通过一个栈来保存遍历过程中的父节点,栈不空且当前节点不为空时执行循环
首先向左遍历,将遍历过程中的根节点的值存入数组,到达没有左子树的叶节点时退出
取出栈顶的节点,让当前指针指向栈顶节点的右节点,也就是向右遍历一次。
代码:
/**
* 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> preorderTraversal(TreeNode *root) {
vector<int> res;
TreeNode *cur=root;
if(!cur) return res;
stack<TreeNode*> stk;
while(!stk.empty()||cur)
{
while(cur)
{
stk.push(cur);
res.push_back(cur->val);
cur=cur->left;
}
TreeNode *tmp=stk.top();
stk.pop();
cur=tmp->right;
}
return res;
}
};
中序遍历
问题描述:
思路
和前序的思路一致,区别在于什么时候访问根节点,在左循环结束,访问根节点时将值入数组
代码
/**
* 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> inorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode* cur=root;
if(!root) return res;
stack<TreeNode*> stk;
while(!stk.empty()||cur)
{
while(cur)
{
stk.push(cur);
cur=cur->left;
}
TreeNode *temp=stk.top();
stk.pop();
res.push_back(temp->val);
cur=temp->right;
}
return res;
}
};
后序遍历
问题描述
思路:
用堆栈保存遍历过程中的父节点,栈顶为当前遍历的父节点
- 和前序思路一致,根节点入栈。
- 右子树存在的情况下,第一次访问右子树,
- 走一次while循环,将val导入res中同时将pre更新为右子树。
- root先指向左子树,然后指向栈顶元素根节点,此时符合if中
root->right==pre;
- 因此,根节点元素加入到结果中,继续指向栈顶元素。
代码:
/**
* 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> postorderTraversal(TreeNode *root) {
vector<int> res;
if (root == nullptr) {
return res;
}
stack<TreeNode *> stk;
TreeNode *prev = nullptr;
while (root != nullptr || !stk.empty()) {
while (root != nullptr) {
stk.emplace(root);
root = root->left;
}
root = stk.top();
stk.pop();
if (root->right == nullptr || root->right == prev) {
res.emplace_back(root->val);
prev = root;
root = nullptr;
} else {
stk.emplace(root);
root = root->right;
}
}
return res;
}
};
层次遍历
问题描述
思路
设置一个队列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:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> res;
if(!root)return res;
queue<TreeNode*>q;
q.push(root);
while(!q.empty()){
vector<int> level;
int len = q.size();
while(len -- ){
auto t = q.front();
q.pop();
level.push_back(t->val);
if(t->left)q.push(t->left);
if(t->right)q.push(t->right);
}
res.push_back(level);
}
return res;
}
};
N叉树前序遍历
问题描述
思路
类似于二叉树前序遍历,只有在子节点入栈这一步需要反向入栈(栈是先入后出,二叉树同样也是先入右节点再入左节点),每次取栈顶元素值入结果就可以。
代码
class Solution {
public:
vector<int> preorder(Node* root) {
vector<int> res;
if(!root) return res;
stack<Node*> stk;
stk.push(root);
while(!stk.empty())
{
Node* node=stk.top();
stk.pop();
res.push_back(node->val);
for(auto it=node->children.crbegin();it!=node->children.crend();it++)
{
stk.push(*it);
}
}
return res;
}
};
N叉树后序遍历
问题描述
思路
如图所示n叉树,如果按前序遍历,结果为:
135624
前序遍历是从左向右访问,如果是从右向左访问为:
142365
而后序遍历的结果为
563241
由此可知,将前序遍历的入栈顺序改变一下,最后将返回的结果翻转就可以得到后序遍历的结果
代码
class Solution {
public:
vector<int> postorder(Node* root) {
vector<int> res;
stack<Node*> stk;
if(root)
{
stk.push(root);
while(!stk.empty())
{
root=stk.top();
stk.pop();
res.push_back(root->val);
for(auto child:root->children)
{
stk.push(child);
}
}
}
reverse(res.begin(),res.end());
return res;
}
};