【数据结构与算法分析】0基础带你学数据结构与算法分析06--树(TREE)

news/2024/5/4 8:37:19/文章来源:https://blog.csdn.net/qq_62464995/article/details/127532573

目录

前言

树的属性 

树的实现

树的遍历与应用

深度有限遍历 (DFS)

广度优先遍历 (BFS) 


Not all roots are buried down in the ground, some are at the top of a tree.

— Jinvirle

前言

Tree 是一些结点的集合,这个集合可以是空集;若不是空集,则 Tree 是由称为 的结点 r 以及零或多个非空的子树 T1,T2,⋯ ,​ 组成,这些子树的根都与 r 有一条有向边 (edge) 连接。这些子树的根被称为根 r 的孩子 (child),而 r 是这些 child 的父亲 (parent)。 

树的属性 

根据给出的树的递归定义,可以发现一个树是由 N 个 node 和 N−1 条 edge 的集合。而除 root 外的所有 node 都有一个由其 parent 指向它的 edge。在树中有一些特殊的属性是需要注意的,这里先给出相关概念与示例,如果不是很理解,可以通过结合示例来理解这些概念。

结点的度 (degree)

        一个节点含有的子树的个数称为该节点的度

树的度 (degree of tree)

        一棵树中最大的 node degree 称为树的度

叶结点 (leaf)

        或称终端结点,如果结点满足 degree=0 则该结点为叶结点

分支结点 (branch node)

        或称内部结点 (internal node)、非终端结点,度不为 0 的结点

层次 (level)

        从 root 开始,root 所在的层为第 1 层,root 的 child 为第二层,以此类推

关系

        树就像一本族谱,从 root 开始结点直接有一定的亲缘关系

  • 兄弟 (sibling): 具有相同父节点的节点互为兄弟节点
  • 叔父 (uncle): 父结点的兄弟结点为该结点的叔父结点
  • 堂兄弟: 父结点在同一层的结点互为堂兄弟

 

路径 (path)

结点 n1,n2,⋯ ,nk​ 的一个序列,使得对于 1≤i<k 满足 ni 是 ni+1 的 parent,则这个序列被称为从 n1​ 到结点 nk​ 的 path。其路径长度 (length) 为路径上的 edge 的数量,即 k−1 。特别地,每个结点到自己的 path lenth 为 0

深度 (depth)

对于结点 ni​ ,从 root 到 ni​ 的唯一路径的长度 (Depthroot=0)

高度 (height)

对于结点 ni​ ,从 ni 到 leaf 的最长路径长度 (Heightleaf=0)

树的高度

或称树的深度,其总是等于根的高度,或最深的结点的深度,可以认为一棵空树的高度为 −1

祖先 (ancestor)

对于结点 ni 与 nj 存在一条 ni​ 到 nj​ 的路径,那么称 ni​ 是 nj​ 的祖先 (ancestor),而 nj​ 是 ni 的 后裔 (descendant)

距离 (distance)

对于结点 ni​ 与 nj ,从最近的公共祖先结点 nk​ 分别到它们的路径长度之和被称为距离 (distance)。特别地,如果 ni=nk​ ,则 ni 与 nj 的距离为 ni​ 到 nj 的路径的长度

 注:

 严蔚敏老师的数据结构中,或者往常的实现中,根的高度为 1,而叶的深度也为 1,树的高度一般指其最大的层次,因此认为空树的高度为 0。

 树的实现

实现树的一种方法是在每一个结点上,除数据外还需要一些链域来指向该结点的每个子结点,然而由于每个结点的子结点数量是不确定的,我们不能直接建立到各个子结点的直接链接。如果申请一定大小的空间以存放子结点,则可能会造成空间的浪费,或不足。因此我们链表的形式存储子结点,而父结点中只存储第一个子结点的指针,如果该链域为空则意味着该结点是叶结点 (degree=0。每个结点中存在一个指向其下一个兄弟的指针,为遍历父结点的所有孩子提供了方法,当该结点 next_sibling=nullptr 时意味着这是父结点的最后一个子结点。 

struct TreeBaseNode {TreeBaseNode* first_child;TreeBaseNode* next_sibling;
};
template <class Element>
struct TreeNode {Element data;
};

如果我们用这个结构实现上述图示的树,可以画一下其表示。

 可以发现,除非该结点是 leaf,否则我们很难判断该结点的 degree。且在计算深度与距离时,要十分小心在兄弟间步进,因为兄弟间步进并不会增加其与 parent 的距离。

树的遍历与应用

观察你系统中的文件系统,回到文件系统的顶层 / (root),并浏览一些目录你会发现, 整个目录结构与 tree 是类似的,我们也常常将其称为目录树。

 这颗目录树稍微有些复杂了,不过问题不大。一般文件系统中采用路径名来访问一个文件,而我们可以像遍历树一样遍历这个文件系统,将每个文件打印出来,并按照层级来缩进文件名称。

深度有限遍历 (DFS)

给出一个代码实现:

void filesystem::list_all(file& f, int depth = 0) const {print_name(f, depth);  // 打印文件的名称if (is_directory(f)) {for (file p : get_file_list(f)) { // 遍历目录中的每个文件list_all(p, depth + 1);}}
}

最终的输出结果可能是:

/|--- mnt/|--- home/|--- GinShio/|--- usr|--- LICENSE|--- lib/|--- libQt5Core.so|--- X11/|--- display-manager|--- etc/|--- displaymanagers/|--- console|--- lightdm|--- sddm|--- xdm|--- libstdc++.so.6|--- mozilla/|--- kmozillahelper|--- bin/|--- latexmk|--- pdftk|--- zsh
.....
.....

在遍历中,每访问一个结点时,对结点的处理工作总是比其子结点的处理先进行,这种先处理根再处理子结点的策略被称为 前序遍历 (preorder traversal)。而另一种常用的遍历方法是 后序遍历 (postorder traversal),即在结点的所有子结点处理完成后再对其进行处理。无论这两种遍历的哪一个,在遍历这个树时总是可以在 O(N) 的时间复杂度里完成。对于目录的 postorder traversal 留给读者思考并实现。

现在考虑这两种算法有什么共通的特点。有没有发现它们都是在一棵子树上处理完所有结点之后再转移到另一棵子树上,这种一直向着 child 递归,直到全部递归结束时再向 sibling 递归的算法,就被称之为 深度优先搜索 (Depth-first Search, DFS)。由于 DFS 使用递归算法,因此 DFS 总能被改写为 loop,非 tail recursion 的递归有可能需要 stack 的帮助才能改为 loop。

 

广度优先遍历 (BFS) 

请回看 树的实现 一节的图,图中的树如果以一层一层遍历,当一层的所有结点都被遍历完时,再进入更深一层,从这层的第一个结点开始处理。这种遍历方式被称为 广度优先遍历 (Breadth-first Search, BFS) 或者是层序遍历。

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

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

相关文章

中国锚杆行业竞争格局及投资风险分析报告

锚杆的概念 锚杆(又称土锚杆、土钉)是在天然土层侧壁钻孔&#xff0c;放置拉杆&#xff0c;注浆锚固而成。根据所用材料&#xff0c;拉杆可分为粗钢筋、高强度钢丝束、钢绞线等。通过计算确定了侧墙上锚杆的截面积、层数、间距和长度。钻孔直径应由设计确定。常用的孔道灌浆有水…

【QT + OsgEarth】(四)加载国界线矢量图

效果图 实现过程 获取国界线矢量图在.earth文件中加载矢量图文件在Qt程序中获取图层节点并控制参数 加载矢量图文件 < image > 标签定义要栅格化的shp文件 driver&#xff1a;使用agglite&#xff0c;将矢量文件栅格成为栅格文件< features > 子标签读取shp文件…

亿可控_第3章 指标数据持久化与设备详情展示

亿可控_第3章 指标数据持久化与设备详情展示 文章目录亿可控_第3章 指标数据持久化与设备详情展示第3章 指标数据持久化与设备详情展示学习目标1. InfluxDB入门及介绍1.1 InfluxDB简介1.2 InfluxDB相关概念1.3 InfluxDB的基本操作1.3.1 InfluxDB数据库操作1.3.2 InfluxDB数据表…

SANGFOR深信服短信插件

设置说明 第一步&#xff1a;先配置短信通知服务器&#xff08;以下以HTTP为例&#xff09;。 步骤1、设置短信通知服务器&#xff0c;在[系统管理/系统配置/高级配置/通知设置]&#xff0c;点击<新增短信通知服务器>&#xff0c;勾选启用&#xff0c;可启用短信通知服…

mdio bcm5482访问

查看硬件原理图&#xff0c;5482通过mdio访问自己的寄存器&#xff0c;M4通过cpld对5482进行初始化操作(复位/解复位&#xff09; 可以看到bcm5482的MDC和MDIO用的是port P 的pin4和pin5,所以基地址为GPIO_PORTP_BASE. 对应的分别是引脚4和引脚5&#xff0c;所以由此可以封装出…

SHEIN算法工程师面试题7道|含解析

8本电子书免费送给大家&#xff0c;见文末。 1、数据处理的常用方法有哪些&#xff1f; 对于离群点 当作缺失值进行处理删掉离群点所在的样本实用统计值进行填充 对于缺失值 可以用均值或均位数进行填充可以用特定值&#xff0c;如-1可以用np.nan表示 对于类别特征 编码方…

SPI示例学习

Service Provider Interface 它是从Java 6开始引入的&#xff0c;是一种基于ClassLoader来发现并加载服务的机制。 服务发现机制&#xff1a;通过在ClassPath路径下的META-INFO/services文件夹中查找文件&#xff0c;并自动加载文件里所定义的类。 SPI机制可以很好的解决不同…

到了2023年,PMP项目管理师证书含金量会如何?考试难度大么?

先介绍一下PMP PMP考试是由PMI(美国项目管理协会Project Management Institute)组织和出题,严格评估项目管理人员知识技能是否具有高品质的资格认证考试。1999年&#xff0c;PMP考试在所有认证考试中第一个获得ISO9001国际质量认证,从而成为全球最权威的认证考试之一。 pmp考…

Oracle技术分享 数据库序列间断场景

文档课题&#xff1a;模拟数据库序列间断场景. 1、概念 Gaps insequence values can occur when: a、Arollback occurs 应用出现回滚&#xff0c;但序列不会回滚 b、Thesystem crashes c、Asequence is used in another table 2、实际操作2.1、系统crash SQL>selec…

云原生时代下 K8s CGroup/CRI 的优劣势

目录前言一、CGroup1.1 基本概念1.2 cgroupfs 驱动1.2.1 基本概念1.2.2 什么是 cgroup v21.2.3 cgroup v2 使用要求1.3 systemd cgroup 驱动1.3.1 基本概念1.3.2 kubelet 设置 cgroup 驱动二、CRI2.1 Containerd2.1.1 基本概念2.1.2 配置 CGroup 驱动2.2 CRI-O2.2.1 基本概念2.…

【LeetCode每日一题】【单调队列】2022-10-26 862. 和至少为K的最短子数组 Java实现

文章目录题目链接题目思路前缀和暴力法优化一优化二另一种写法题目链接 https://leetcode.cn/problems/shortest-subarray-with-sum-at-least-k/ 题目 思路 https://leetcode.cn/problems/shortest-subarray-with-sum-at-least-k/solution/liang-zhang-tu-miao-dong-dan-dia…

【电子通识】芯片资料(数据手册/规格书)查询常用网站和方法

目录 1.AlldataSheet 网站&#xff08;建议使用&#xff09; 2.ICpdf 网站 3.CIC中国IC网 网站 4.datasheet&#xff08;不建议使用&#xff09; 5.半导小芯 &#xff08;建议使用&#xff09; 6.立创商城 &#xff08;建议使用&#xff09; 在做硬件的芯片选型、产品维修…

MySQL体系结构

MySQL体系结构初识MySQLOLTPOLAPSQL数据库术语MySQL体系结构连接池缓冲组件执行select语句的过程总结后言初识MySQL 按照数据结构来组织、存储和管理数据的仓库&#xff1b;是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。 MySQL是关系型数据库&…

从位运算理解位图

位图是一种较难理解的数据结构&#xff0c;想了解位图&#xff0c;我需要先温习一下基础&#xff0c;复习下一些二进制的知识 位运算 1个字节8个二进制位 二进制每逢二进一&#xff0c;下面是二进制对应的十进制转换方式 二进制十进制0000 00012^010000 00102^120000 00112…

Shell编程案例

Shell编程案例 文章目录Shell编程案例熟悉shell编程的有关机制&#xff0c;如标准流。学习Linux环境变量设置文件及其内容/etc/profile/etc/bashrc/etc/environment~/.profile~/.bashrc熟悉编程有关基础命令技巧和规则sed掌握shell 程序执行的三种基本方式使用for循环语句,完成…

万字长文的CSS与JavaScript简易学习

近期学习web笔记&#xff0c;可供参考 目录 css: css导入方式&#xff1a; css选择器&#xff1a; javascript: javascript介绍&#xff1a; js引入方式&#xff1a; js书写语法&#xff1a; js变量&#xff1a; 5种原始类型&#xff1a; 运算符&#xff1a; JavaScr…

Spring Aop的学习(一):Spring Aop的简单入门

1. 什么是AOP AOP(Aspect Oriented Programming):面向切面编程,是OOP(面向对象编程)的一个延续,其和OOP一样,也是一种编程思想。不过AOP是一种横向开发模式。 2. AOP的作用及应用场景作用 AOP的主要作用就是减少代码量,提高代码的可重用性,有利于未来的可操作性与可维护性…

2022-2023-1 20221424《计算机基础与程序设计》第9周学习总结

2022-2023-1 20221424《计算机基础与程序设计》第9周学习总结 作业信息这个作业属于哪个课程 2022-2023-1-计算机基础与程序设计这个作业要求在哪里 2022-2023-1计算机基础与程序设计第一周作业这个作业的目标 操作系统责任,内存与进程管理,分时系统,CPU调度,文件、文件系统…

《JavaSE-第十五章》之文件(二)

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页&#xff1a;KC老衲爱尼姑的博客主页 博主的github&#xff0c;平常所写代码皆在于此 刷题求职神器 共勉&#xff1a;talk is cheap, show me the code 作者是爪哇岛的新手&#xff0c;水…

neovim图标显示乱码,utf8字体显示乱码(Windows10和Centos安装nerd-fonts)

前言 作为一名想成为大神的菜鸟程序员&#xff0c;一个牛X的代码编辑环境是必不可少的&#xff0c;在这里我推荐neovim和emacs。我使用的是neovim&#xff0c;github上有neovim-from-scratch工程可以一步一步学习搭建&#xff0c;B站上也有相关视频可供学习&#xff0c;在这里…