题目:
给定一个 n 叉树的根节点 root
,返回 其节点值的 前序遍历 。
n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null
分隔(请参见示例)。
import java.util.*;
/** 思路:使用栈, 从根节点开始向 叶子节点 进行遍历,
在遍历的同时添加节点到 ans(ans是存储结果的)中。
同时创建一个哈希表,该哈希表是存储 节点在子节点集合中的位置,
根据该位置可以更新子节点。 遍历到叶子节点后,
* 从栈中取出一个节点遍历该节点的子节点,重复操作即可实现N叉树前序遍历
* @auther start
* @create 2023-11-15 9:01
*/
public class Solution {
List<Integer> ans = new ArrayList<>();
public List<Integer> preorder(Node root) {
//方法一,递归
// dfs(root);
// return ans;
//方法二,使用栈
List<Integer> res = new ArrayList<>();
if (root == null) return res;
//判断子集是否访问过
Map<Node,Integer> map = new HashMap<>();
//创建栈
Deque<Node> stack = new ArrayDeque<>();
Node node = root;
//栈不为空或者node不为空继续遍历全部的子节点
while (!stack.isEmpty() || node != null) {
//添加节点到ans中
while (node != null) {
//添加到集合中
res.add(node.val);
//入栈
stack.push(node);
//寻找子节点
List<Node> children = node.children;
//判断是否有子节点
if (children != null && children.size() > 0) {
//如果有子节点,将该节点添加到map中
map.put(node,0);
//获取第一个子节点
node = children.get(0);
} else {
node = null;
}
}
//出栈,寻找该节点的其他节点
node = stack.peek();
//获取该节点的下一个字节点,若该节点没有子节点则index为0.
int index = map.getOrDefault(node,-1) + 1;
//获取子节点的全部集合
List<Node> chirdren = node.children;
//判断是否存在子节点
if (chirdren != null && chirdren.size() > index) {
//存在子节点,添加到map中。
map.put(node,index);
//获取子节点
node = chirdren.get(index);
} else {
//没有子节点,将此节点出栈
stack.pop();
//移除map中的记录
map.remove(node);
node = null;
}
}
return res;
}
void dfs(Node root) {
if (root == null) return;
ans.add(root.val);
for (Node node : root.children) dfs(node);
}
}
class Node {
public int val;
//节点的孩子节点都是从左到右依次存储
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};