【栈】N 叉树的前序遍历

题目:

给定一个 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;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值