数据结构与算法——N叉树(自学笔记)

本文参考 N 叉树 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台

遍历

img

  • 前序遍历:A->B->C->E->F->D->G
  • 后序遍历:B->E->F->C->G->D->A
  • 层序遍历:A->B->C->D->E->F->G

(中序遍历只在二叉树有明确定义)

前序遍历

递归

与二叉树一样

import java.util.*;

// 定义N叉树节点
class Node{
    public int val;
    public List<Node> children; // 使用链表定义子节点

    public Node(){}

    public Node(int val){
        this.val = val;
    }

    public Node(int val, List<Node> children){
        this.val = val;
        this.children = children;
    }
}

class Solution {

    public List<Integer> preorder(Node root){
        List<Integer> res = new ArrayList<Integer>();
        preorderRecursion(root,res);
        return res;
    }
    public void preorderRecursion(Node root, List<Integer> res){
        if(root == null){
            return;
        }
        res.add(root.val);
        for(Node node : root.children){
            preorderRecursion(node, res);
        }
    }
}
  • 时间复杂度:O(N),其中 N 是树的节点数。
  • 空间复杂度:O(N),即树的高度,最坏情况下递归栈和结果存储的空间需要O(N)的空间。

迭代

与二叉树不一样,很巧妙

class Solution {
    public List<Integer> preorder(Node root){
        List<Integer> res = new ArrayList<Integer>();
        if(root == null){
            return res;
        }
        Deque<Node> stack = new LinkedList<Node>();
        stack.push(root);

        while(!stack.isEmpty()){
            Node node = stack.pop();
            res.add(node.val);
            // 逆序入栈
            for(int i = node.children.size() - 1; i >= 0 ; i--){ 
                stack.push(node.children.get(i)); 
            }
        }
        return res;
    }
}
  • 时间复杂度:O(N),其中 N 是树的节点数。
  • 空间复杂度:O(N),即树的高度,最坏情况下递归栈和结果存储的空间需要O(N)的空间。

后序遍历

递归

class Solution {
    public List<Integer> postorder(Node root){
        List<Integer> res = new ArrayList<Integer>();
        postorderRecursion(root,res);
        return res;
    }
    public void postorderRecursion(Node root, List<Integer> res){
        if(root == null){
            return;
        }
        for(Node node : root.children){
            postorderRecursion(node, res);
        }
        res.add(root.val); // 与前序遍历的唯一区别
    }
}

迭代

与前序遍历相似

class Solution {
    public List<Integer> postorder(Node root) {
        // 创建一个列表用来存储后序遍历的结果
        List<Integer> res = new ArrayList<>();
        

        // 如果树为空,直接返回空结果
        if (root == null) {
            return res;
        }
    
        // 使用栈进行遍历,栈用来模拟递归
        Deque<Node> stack = new ArrayDeque<Node>();
        
        // 创建一个集合,用来记录已经访问过的节点
        Set<Node> visited = new HashSet<Node>();
        
        // 将根节点推入栈中
        stack.push(root);
        
        // 遍历栈中的节点,直到栈为空
        while (!stack.isEmpty()) {
            // 获取栈顶的节点
            Node node = stack.peek();
            
            // 如果当前节点没有子节点(叶子节点),或者子节点已经遍历过
            if (node.children.size() == 0 || visited.contains(node)) {
                // 弹出栈顶元素,并将其值加入结果列表
                stack.pop();
                res.add(node.val);
                // 继续下一次循环
                continue;
            }
            
            // 如果当前节点有未访问的子节点,逆序将子节点压入栈中
            for (int i = node.children.size() - 1; i >= 0; --i) {
                stack.push(node.children.get(i));
            }
            
            // 将当前节点标记为已访问
            visited.add(node);
        }
        
        // 返回存储后序遍历结果的列表
        return res;
    }

}
  • 时间复杂度:O(N),其中 N 是树的节点数。
  • 空间复杂度:O(N),即树的高度,最坏情况下递归栈和结果存储的空间需要O(N)的空间。

层序遍历

常规方法

class Solution {
    public List<List<Integer>> levelOrder (Node root){
        List<List<Integer>> res = new ArrayList<>();
        if(root == null){
            return res;
        }
        Queue<Node> queue = new LinkedList<>();
        Node node = root;
        queue.offer(node);
        while(!queue.isEmpty()){
            List<Integer> level = new ArrayList<>(); // 创建子链表
            int size = queue.size(); // 计算当前层的大小
            for(int i = 0; i < size; i++){
                node = queue.poll(); // 把当前层的节点依次弹出,并加入小链表
                level.add(node.val);
                for(Node p : node.children){
                    queue.offer(p); // 把下一层的节点依次加入队列
                }
            }
            res.add(level); // 将小链表加入大链表
        }
        return res;
    }
}
  • 时间复杂度:O(N),其中 N 是树的节点数。
  • 空间复杂度:O(N),即树的高度,最坏情况下递归栈和结果存储的空间需要O(N)的空间。

递归

N叉树的最大深度

class Solution {
    public int maxDepth(Node root){
        if(root == null){
            return 0;
        }
        int maxNmu = 0;
        List<Node> children = root.children;
        if (children != null){ // 增强for可以自动处理空集合,但不能处理null,最好添加判断
            for(Node p : children){
                maxNmu = Math.max(maxNmu,maxDepth(p)); // 找出最深层
            }
        }
        return maxNmu + 1;
    }
}

时间复杂度:O(n),其中 n 为 N 叉树节点的个数。每个节点在递归中只被遍历一次。

空间复杂度:O(height),其中 height 表示 N 叉树的高度。递归函数需要栈空间,而栈空间取决于递归的深度,因此空间复杂度等价于 N 叉树的高度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/925647.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringSecurity6

1.快速入门 2.SpringSecurity底层原理 使用的是委托过滤器,委托过滤器实际上就是 sevlet 过滤器 将自己放入Sevlet环境下 然后里面是一个 过滤器链代理 代理类下又是一个代理过滤器链的集合, 对于不同请求可以有不同的过滤器链, springsecurity有个默认的过滤器链 Defau…

芯片测试-RF中的S参数,return loss, VSWR,反射系数,插入损耗,隔离度等

RF中的S参数&#xff0c;return loss, VSWR&#xff0c;反射系数&#xff0c;插入损耗&#xff0c;隔离度 &#x1f4a2;S参数&#x1f4a2;&#x1f4a2;S11与return loss&#xff0c;VSWR&#xff0c;反射系数&#x1f4a2;&#x1f4a2;S21&#xff0c;插入损耗和增益&#…

前端页面或弹窗在线预览文件的N种方式

需求&#xff1a;后端返回给前端一个地址后&#xff0c;在前端页面上或则在弹框中显示在线的文档、表格、图片、pdf、video等等&#xff0c;嵌入到前端页面 方式一&#xff1a; 使用vue-office 地址&#xff1a;vue-office简介 | vue-office 个人感觉这个插件是最好用的&#x…

剪映自动批量替换视频、图片素材教程,视频批量复刻、混剪裂变等功能介绍

一、三种批量替换模式的区别 二、混剪裂变替换素材 三、分区混剪裂变替换素材 四、按组精确替换素材 五、绿色按钮教程 &#xff08;一&#xff09;如何附加音频和srt字幕 &#xff08;二&#xff09;如何替换固定文本的内容和样式 &#xff08;三&#xff09;如何附加…

【天地图】HTML页面实现车辆轨迹、起始点标记和轨迹打点的完整功能

目录 一、功能演示 二、完整代码 三、参考文档 一、功能演示 运行以后完整的效果如下&#xff1a; 点击开始&#xff0c;小车会沿着轨迹进行移动&#xff0c;点击轨迹点会显示经纬度和时间&#xff1a; 二、完整代码 废话不多说&#xff0c;直接给完整代码&#xff0c;替换…

Node报错:npm error code ETIMEDOUT

1、报错详细信息 npm error code ETIMEDOUT npm error syscall connect npm error errno ETIMEDOUT npm error network request to https://registry.npmjs.org/express failed, reason: connect ETIMEDOUT 104.16.1.35:443 npm error network This is a problem related to ne…

FPGA工具链及功能介绍

一、处理流程 把verilog等源码&#xff0c;变为FPGA中可执行的比特流文件&#xff0c;主要包含这些步骤&#xff1a; 步骤功能转译将verilog代码转化为更详细的语法&#xff0c;增加更多细节内容技术映射将每个vrilog用到的模块&#xff0c;对应到FPGA的物理器件上优化优化冗余…

自然语言能开发项目? 基于Agent的AI开发团队提示词分享

文章目录 概述真正落地效果(参考codeflying)开发团队各角色提示词产品经理软件架构师UI/UX 设计师前端开发工程师后端开发工程师软件测试工程师网络安全专家概述 自然语言开发应用?这在以前是天方夜谭,可是在AIGC时代,这变成可能。原理就是基于大模型和智能体技术的多智能…

【MQ】大白话告诉你什么是MQ,没有比这还详细还易懂的文章了吧,以RabbitMQ为例,从小白到大神

目录 分布式系统通信方式 MQ选型与应用场景 应用场景&#xff08;优势&#xff09; RabbitMQ工作模型 RabbitMQ简介 RabbitMQ 工作模型&#xff08;流程&#xff09;​编辑 Docker安装配置RabbitMQ RabbitMQ管理控制台 RabbitMQ 简单模式构建生产者 RabbitMQ 简单模式…

html+css+js网页设计 去哪旅游官网6个页面

htmlcssjs网页设计 去哪旅游官网6个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#x…

AI与ArcGIS Pro的地理空间分析和可视化

AI思维已经成为一种必备的能力&#xff0c;ArcGIS Pro3的卓越性能与ChatGPT的智能交互相结合&#xff0c;将会为您打造了一个全新的工作流程! 那么如何将火热的ChatGPT与ArcGIS Pro3相结合&#xff0c;使我们无需自己进行复杂的编程&#xff0c;通过强大的ChatGPT辅助我们完成地…

Java Collection

Collection——狭义上的集合 接口Collection派生了三大类集合&#xff0c;分别是List、Set、Queue/Deque。 List&#xff0c;有序集合&#xff0c;提供了访问、插入、删除等操作。Set&#xff0c;不允许重复元素的&#xff0c;这是和List最明显的区别&#xff0c;不存在两个对…

深度学习基础1

目录 1. 深度学习的定义 2.神经网络 2.1. 感知神经网络 2.2 人工神经元 2.2.1 构建人工神经元 2.2.2 组成部分 2.2.3 数学表示 2.2.4 对比生物神经元 2.3 深入神经网络 2.3.1 基本结构 2.3.2 网络构建 2.3.3 全连接神经网络 3.神经网络的参数初始化 3.1 固定值初…

前端js面试知识点思维导图(脑图)

如果看着不清晰可以去https://download.csdn.net/download/m0_73761441/90058523访问下载&#xff0c;无需积分 使用百度脑图制作&#xff0c;可以一键导入下面的文本生成自己的脑图 js相关面试题、知识点 数据类型 1. 数据类型分类&#xff1f;分别包含&#xff…

单片机知识总结(完整)

1、单片机概述 1.1. 单片机的定义与分类 定义&#xff1a; 单片机&#xff08;Microcontroller Unit&#xff0c;简称MCU&#xff09;是一种将微处理器、存储器&#xff08;包括程序存储器和数据存储器&#xff09;、输入/输出接口和其他必要的功能模块集成在单个芯片上的微型…

排序(数据结构)

排序&#xff1a; 所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 常见排序法 . 常见排序算法的实现 插入排序 1.直接插入排序 2.希尔排序( 缩小增量排序&#xff09; 希尔排序的特性总结&#x…

web安全攻防入门教程

Web安全攻防入门教程 Web安全攻防是指在Web应用程序的开发、部署和运行过程中&#xff0c;保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现&#xff0c;还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。 本教程将带你入门Web安全攻…

houdini肌肉刷pin点的方法

目标&#xff1a;产生gluetoanimation这个属性 主要节点&#xff1a;attribute paint(或者muscle paint) 步骤1&#xff1a; 导入肌肉资产 导入的是rest shape的肌肉 在有侧边栏可以打开display group and attribute list&#xff0c;方便查看group。不同的肌肉块按照muscl…

Online Judge——【前端项目初始化】项目通用布局开发及初始化

目录 一、新建layouts二、更新App.vue文件三、选择一个布局&#xff08;Layout&#xff09;四、通用菜单Menu的实现菜单路由改为读取路由文件 五、绑定跳转事件六、同步路由到菜单项 一、新建layouts 这里新建一个专门存放布局的布局文件layouts&#xff1a; 然后在该文件夹&…

lora微调大模型Qwen2.5_32B

最近有在尝试用lora微调Qwen大模型&#xff0c;在这里主要记录下实践过程。Qwen模型下载可以去魔塔社区&#xff0c;我这里是提前下载好了放在/public/DownloadedModels下。LLamaFactory源码地址&#xff1a;GitHub - hiyouga/LLaMA-Factory: Unified Efficient Fine-Tuning of…