题目概述
给定一个 N 叉树,返回其节点值的前序遍历 ,N叉树节点定义如下:
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
思考过程
递归法
树的遍历问题基本可以由递归实现,递归的实现需要考虑三点:
- 递归终止条件
- 递归的返回值
- 每一次递归需要处理的事
那么回到N叉树遍历,相比于二叉树,无非是根节点的个数由左右孩子变成了很多孩子,那么在N叉树遍历时,只需要考虑如何去除N个孩子即可,从Node定义可知,N个子孩子存储在一个vector
数组中,那么主需要利用一个for循环
即可取出N个孩子,代码如下:
void dfs(Node* root, vector<int>& vt) {
// 递归终止条件:为空则返回
if (root == NULL) return ;
// 每一次递归需要做的事:将当前节点的值加入到输出数组中
// 返回值即为前序遍历结果:vt数组
vt.push_back(root->val);
vector<Node*> child = root->children;
for(auto c:child) dfs(c, vt);
}
vector<int> preorder(Node* root) {
vector<int> ans;
dfs(root, ans);
return ans;
}
迭代法
同样从二叉树开始考虑,使用stack先进后出的特性
即可实现前序遍历和后序遍历
- 首先考虑极端情况:根节点为空->直接返回空结果数组
- 创建一个
stack
用于存储将要处理的节点,首先将跟节点加入 - 使用
while循环
控制当stack
不为空时,循环处理 - 创建一个指向当前节点(stack的栈顶元素)的
Node
指针,并将其节点值加入最终输出vector
中,并从栈中删除栈顶元素 - 根据
stack
先进后出的特性,需要先加入当前节点的最后一个孩子,最后加入第一个孩子,才能在取出数据时达到前序遍历的要求
步骤5
有两种实现方式,具体如代码
法一:使用两个栈
vector<int> preorder(Node* root) {
vector<int> vt;
if (root == NULL) return vt;
stack<Node*> node;
node.push(root);
while (!node.empty()) {
Node* cur = node.top();
node.pop();
vt.push_back(cur->val);
vector<Node*> child = cur->children;
stack<Node*> temp;
for (auto c:child) temp.push(c);
while(!temp.empty()) {
node.push(temp.top());
temp.pop();
}
}
return vt;
}
法二:使用一个栈
vector<int> preorder(Node* root) {
vector<int> vt;
if (root == NULL) return vt;
stack<Node*> st;
st.push(root);
while(!st.empty()) {
Node* cur = st.top();
st.pop();
vt.push_back(cur->val);
for(int i = cur->children.size() - 1; i >= 0; i--) {
st.push(cur->children[i]);
}
}
return vt;
}