LeetCode中N叉树的前序中序后序递归和非递归写法
相关题
589. 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:
vector<int> preorder(Node* root) {
if (!root) return {};
helper(root);
return res;
}
private:
void helper(Node* root) {
if (!root) return;
res.push_back(root->val);
for (auto &a : root->children) {
helper(a);
}
}
vector<int> res;
};
- 非递归写法
之前做过二叉树的前序遍历的非递归写法,采取的方法是,先访问根节点,然后将右子树根节点入栈,再将左子树根节点入栈,照着这个模板写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:
vector<int> preorder(Node* root) {
if (!root) return {};
stack<Node*> st{{root}};
vector<int> res;
while (!st.empty()) {
Node* t = st.top(); st.pop();
res.push_back(t->val);
for (int i = t->children.size() - 1; i >= 0; --i) {
st.push(t->children[i]);
}
}
return res;
}
};
429. 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:
vector<vector<int>> levelOrder(Node* root) {
if (!root) return {};
queue<Node*> q{{root}};
vector<vector<int>> res;
while (!q.empty()) {
vector<int> tmp;
for (int k = q.size(); k > 0; --k) {
Node* t = q.front(); q.pop();
tmp.push_back(t->val);
for (int i = 0; i < t->children.size(); ++i) {
q.push(t->children[i]);
}
}
res.push_back(tmp);
}
return res;
}
};
590. 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:
vector<int> postorder(Node* root) {
helper(root);
return res;
}
private:
vector<int> res;
void helper(Node* root) {
if (!root) return;
for (auto &a : root->children) {
helper(a);
}
res.push_back(root->val);
}
};
- 非递归写法
对前序遍历的代码进行修改即可变成后序遍历的代码,之前的二叉树的后序遍历非递归写法,也提及过这个思路,即前序遍历的序列是根-左-右,而后序遍历的序列是左-右-根,稍微变换一下,即根-右-左,即可通过前序遍历修改得到后序遍历的写法。
/*
// 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> postorder(Node* root) {
if (!root) return {};
vector<int> res;
stack<Node*> st{{root}};
while (!st.empty()) {
Node* t = st.top(); st.pop();
res.push_back(t->val);
for (auto &a : t->children) {
st.push(a);
}
}
reverse(res.begin(), res.end());
return res;
}
};
写在后面
- LeetCode中缺少N叉树的中序遍历题,后期再补上
- 前序、后序遍历结构类似层序,前者是栈,后者是队列
- 前序按照右->左压栈,而后序按照左->右压栈,然后再倒序.