程序设计 树基础

news2024/11/24 22:25:01

✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。
🍎个人主页:小嗷犬的个人主页
🍊个人网站:小嗷犬的技术小站
🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。


本文目录

    • 引入
    • 定义
    • 有关树的定义
      • 适用于无根树和有根树
      • 只适用于有根树
    • 特殊的树
    • 存储
      • 只记录父结点
      • 邻接表
      • 左孩子右兄弟表示法
        • 过程
        • 实现
      • 二叉树
    • 树的遍历
      • 树上 DFS
      • 二叉树上 DFS
        • 前序遍历
        • 中序遍历
        • 后序遍历
        • 反推
      • 树上 BFS
      • 无根树
        • 过程
        • 实现
      • 有根树


引入

图论中的树和现实生活中的树长得一样,只不过我们习惯于处理问题的时候把树根放到上方来考虑。

这种数据结构看起来像是一个倒挂的树,因此得名。


定义

一个没有固定根结点的树称为 无根树(unrooted tree)。无根树有几种等价的形式化定义:

  • n n n 个结点, n − 1 n-1 n1 条边的连通无向图
  • 无向无环的连通图
  • 任意两个结点之间有且仅有一条简单路径的无向图
  • 任何边均为桥的连通图
  • 没有圈,且在任意不同两点间添加一条边之后所得图含唯一的一个圈的图

在无根树的基础上,指定一个结点称为 ,则形成一棵 有根树(rooted tree)。有根树在很多时候仍以无向图表示,只是规定了结点之间的上下级关系,详见下文。


有关树的定义

适用于无根树和有根树

  • 森林(forest):每个连通分量(连通块)都是树的图。按照定义,一棵树也是森林。
  • 生成树(spanning tree):一个连通无向图的生成子图,同时要求是树。也即在图的边集中选择 n − 1 n - 1 n1 条,将所有顶点连通。
  • 无根树的叶结点(leaf node):度数不超过 1 1 1 的结点。
  • 有根树的叶结点(leaf node):没有子结点的结点。

只适用于有根树

  • 父亲(parent node):对于除根以外的每个结点,定义为从该结点到根路径上的第二个结点。 根结点没有父结点。

  • 祖先(ancestor):一个结点到根结点的路径上,除了它本身外的结点。 根结点的祖先集合为空。

  • 子结点(child node):如果 u u u v v v 的父亲,那么 v v v u u u 的子结点。
    子结点的顺序一般不加以区分,二叉树是一个例外。

  • 结点的深度(depth):到根结点的路径上的边数。

  • 树的高度(height):所有结点的深度的最大值。

  • 兄弟(sibling):同一个父亲的多个子结点互为兄弟。

  • 后代(descendant):子结点和子结点的后代。
    或者理解成:如果 u u u v v v 的祖先,那么 v v v u u u 的后代。
    后代

  • 子树(subtree):删掉与父亲相连的边后,该结点所在的子图。
    子树


特殊的树

  • 链(chain/path graph):满足与任一结点相连的边不超过 2 2 2 条的树称为链。

  • 菊花/星星(star):满足存在 u u u 使得所有除 u u u 以外结点均与 u u u 相连的树称为菊花。

  • 有根二叉树(rooted binary tree):每个结点最多只有两个儿子(子结点)的有根树称为二叉树。常常对两个子结点的顺序加以区分,分别称之为左子结点和右子结点。
    大多数情况下,二叉树 一词均指有根二叉树。

  • 完整二叉树(full/proper binary tree):每个结点的子结点数量均为 0 0 0 或者 2 2 2 的二叉树。换言之,每个结点或者是树叶,或者左右子树均非空。
    完整二叉树

  • 完全二叉树(complete binary tree):只有最下面两层结点的度数可以小于 2 2 2,且最下面一层的结点都集中在该层最左边的连续位置上。
    完全二叉树

  • 完美二叉树(perfect binary tree):所有叶结点的深度均相同的二叉树称为完美二叉树。
    完美二叉树

Proper binary tree 的汉译名称不固定,且完全二叉树和满二叉树的定义在不同教材中定义不同,遇到的时候需根据上下文加以判断。

ACMer 所说的「满二叉树」多指完美二叉树。


存储

只记录父结点

用一个数组 parent[N] 记录每个结点的父亲结点。

这种方式可以获得的信息较少,不便于进行自顶向下的遍历。常用于自底向上的递推问题中。

邻接表

  • 对于无根树:为每个结点开辟一个线性列表,记录所有与之相连的结点。

    std::vector<int> adj[N];
    
  • 对于有根树:

    • 方法一:若给定的是无向图,则仍可以上述形式存储。下文将介绍如何区分结点的上下关系。

    • 方法二:若输入数据能够确保结点的上下关系,则可以利用这个信息。为每个结点开辟一个线性列表,记录其所有子结点;若有需要,还可在另一个数组中记录其父结点。

      std::vector<int> children[N];
      int parent[N];
      

      当然也可以用其他方式(如链表)替代 std::vector

左孩子右兄弟表示法

过程

对于有根树,存在一种简单的表示方法。

首先,给每个结点的所有子结点任意确定一个顺序。

此后为每个结点记录两个值:其 第一个子结点 child[u] 和其 下一个兄弟结点 sib[u]。若没有子结点,则 child[u] 为空;若该结点是其父结点的最后一个子结点,则 sib[u] 为空。

实现

遍历一个结点的所有子结点可由如下方式实现。

int v = child[u]; // 从第一个子结点开始
while (v != EMPTY_NODE)
{
    // ...
    // 处理子结点 v
    // ...
    v = sib[v]; // 转至下一个子结点,即 v 的一个兄弟
}

也可简写为以下形式。

for (int v = child[u]; v != EMPTY_NODE; v = sib[v])
{
    // ...
    // 处理子结点 v
    // ...
}

二叉树

需要记录每个结点的左右子结点。

int parent[N];
int lch[N], rch[N];
// -- or --
int child[N][2];

树的遍历

树上 DFS

在树上 DFS 是这样的一个过程:先访问根节点,然后分别访问根节点每个儿子的子树。

可以用来求出每个节点的深度、父亲等信息。

二叉树上 DFS

前序遍历

前序遍历

按照 根,左,右 的顺序遍历二叉树。

void preTrav(BiTree *root)
{
    if (root)
    {
        cout << root->key << " ";
        preTrav(root->left);
        preTrav(root->right);
    }
}

中序遍历

中序遍历

按照 左,根,右 的顺序遍历二叉树。

void midTrav(BiTree *root)
{
    if (root)
    {
        midTrav(root->left);
        cout << root->key << " ";
        midTrav(root->right);
    }
}

后序遍历

后序遍历

按照 左,右,根 的顺序遍历二叉树。

void lastTrav(BiTree *root)
{
    if (root)
    {
        lastTrav(root->left);
        lastTrav(root->right);
        cout << root->key << " ";
    }
}

反推

已知中序遍历序列和另外一个序列可以求第三个序列。

反推

  1. 前序的第一个是 root,后序的最后一个是 root。
  2. 先确定根节点,然后根据中序遍历,在根左边的为左子树,根右边的为右子树。
  3. 对于每一个子树可以看成一个全新的树,仍然遵循上面的规律。

树上 BFS

从树根开始,严格按照层次来访问节点。

BFS 过程中也可以顺便求出各个节点的深度和父亲节点。

无根树

过程

树的遍历一般为深度优先遍历,这个过程中最需要注意的是避免重复访问结点。

由于树是无环图,因此只需记录当前结点是由哪个结点访问而来,此后进入除该结点外的所有相邻结点,即可避免重复访问。

实现

void dfs(int u, int from)
{
    // 递归进入除了 from 之外的所有子结点
    // 对于出发结点,from 为空,故会访问所有相邻结点,这与期望一致
    for (int v : adj[u])
        if (v != from)
            dfs(v, u);
}

// 开始遍历时
int EMPTY_NODE = -1; // 一个不存在的编号
int root = 0;        // 任取一个结点作为出发点
dfs(root, EMPTY_NODE);

有根树

对于有根树,需要区分结点的上下关系。

考察上面的遍历过程,若从根开始遍历,则访问到一个结点时 from 的值,就是其父结点的编号。

通过这个方式,可以对于无向的输入求出所有结点的父结点,以及子结点列表。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Lorilla LLM - 面向API调用生成的专用AI大模型

Gorilla 是一种先进的大型语言模型 (LLM)&#xff0c;旨在与各种 API 有效交互&#xff0c;从而增强 LLM 在实际应用中的功能。 Gorilla LLM的相关链接&#xff1a;官网 | github | 论文。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 1、Gorilla LLM简介 通过使用自…

CentOS 项目作出声明,宣称自家 Linux 社区 “始终向所有人开放”

导读在红帽 RHEL 开源事件后&#xff0c;许多兼容 RHEL 的发行版最近都进行了表态&#xff0c;CentOS 项目也在日前作出了声明&#xff0c;宣称自家社区 “始终向所有人开放”。 据悉&#xff0c;CentOS 项目董事会日前在官方博客发布了一则公告&#xff0c;内容主要涉及“ Ce…

拒绝摆烂!C语言练习打卡第一天

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;每日一练 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ &#x1f5d2;️前言&#xff1a; 在前面我们学习完C语言的所以知识&#xff0c;当…

LangChain手记 Models,Prompts and Parsers

整理并翻译自DeepLearning.AILangChain的官方课程&#xff1a;Models,Prompts and Parsers 模型&#xff0c;提示词和解析器&#xff08;Models, Prompts and Parsers&#xff09; 模型&#xff1a;大语言模型提示词&#xff1a;构建传递给模型的输入的方式解析器&#xff1a;…

NAS搭建指南二——影视资源中心

1. 刮削 这一部分是利用 tinyMediaManager 进行影视资源的评分、简介以及图片的搜集工作tinyMediaManager 官方网站地址下载及安装过程&#xff1a;略我的主要修改的设置项如下所示&#xff1a; 使用方法&#xff1a; a. 点击更新媒体库 b. 选择影片–>右键单击–>…

Ubuntu 20.04(服务器版)安装 Anaconda

0、Anaconda介绍 Anaconda是一个开源的Python发行版本&#xff0c;包含了包括Python、Conda、科学计算库等180多个科学包及其依赖项。因此&#xff0c;安装了Anaconda就不用再单独安装CUDA、Python等。 CUDA&#xff0c;在进行深度学习的时候&#xff0c;需要用到GPU&#xf…

生信分析pandas数据处理 Python简明教程 | 视频18

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

软件开发中常用数据结构介绍:C语言链表

工作之余来写写C语言相关知识&#xff0c;以免忘记。今天就来聊聊C语言链表&#xff0c;我是分享人M哥&#xff0c;目前从事车载控制器的软件开发及测试工作。 学习过程中如有任何疑问&#xff0c;可底下评论&#xff01; 如果觉得文章内容在工作学习中有帮助到你&#xff0c;麻…

干不完根本干不完,我也不想加班,快来围观时间管理大师

时间不够用&#xff0c;怎么办&#xff1f; 成功不靠加班。生产队的驴都不加班&#xff0c;你加什么班&#xff1f;到点就下班&#xff0c;该玩玩&#xff0c;该学习认真学&#xff0c;累了就睡觉。 你可以做任何事&#xff0c;但不必做所有事。 时间管理&#xff0c;不是管…

(十七)大数据实战——Hive的hiveserver2服务安装部署

前言 HiveServer2 是 Apache Hive 的一个服务器端组件&#xff0c;用于支持客户端与 Hive 进行交互和执行查询。HiveServer2服务的作用是提供jdbc/odbc接口&#xff0c;为用户提供远程访问Hive数据的功能。HiveServer2 允许多个客户端同时连接并与 Hive 交互。这些客户端可以通…

HOT91-不同路径

leetcode原题链接&#xff1a;不同路径 题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;…

shell编程免交互

免交互 定义&#xff1a; 一键执行&#xff0c;无需人工干预&#xff0c;不需要人为控制&#xff0c;就可以完成的操作&#xff0c;继续自动化运维 免交互在linux中的运用&#xff1a; 对于Linux操作系统中&#xff0c;有许多操作都会触及到交互&#xff08;根据系统的指示做…

OpenCV项目开发实战--相机校准—并附实例Python/C++代码实现

介绍 相机标定是计算机视觉中的一项基本任务在 3D 重建、对象跟踪、增强现实和图像分析等各种应用中至关重要。准确的校准通过校正失真和估计相机的内在和外在参数来确保精确的测量和可靠的分析。这本综合指南深入探讨了相机校准的原理、技术和算法。我们探索获取相机的内在和…

在 Linux 虚拟机上使用 Azure 自定义脚本扩展版本

参考 azure创建虚拟机,创建虚拟机注意入站端口规则开放80端口、 2.转到资源&#xff0c;点击扩展应用程序&#xff0c;创建存储账户&#xff0c;创建容器&#xff0c;上传文件&#xff0c;选择文件&#xff0c;会自动执行部署。 apt-get update -y && apt-get insta…

电信流失用户画像

三大运营商电信、联通、移动&#xff0c;都想扩大自己的客户群体。据研究&#xff0c;获取新客户所需的成本远高于保留现有客户的成本。因此为了满足在激烈竞争中的优势&#xff0c;提前预测出用户是否会流失&#xff0c;采取保留措施成为一大挑战。本文和你一起探索电信流失客…

挤牙膏的iPhone15真不值,实在太敷衍,看完基本没了购买欲望

随着苹果大概会如往年那样在9月13日发布iPhone15&#xff0c;目前iPhone15四款手机的消息已经基本剧透&#xff0c;没啥秘密可言&#xff0c;从透露的消息可以看出低配的iPhone15实在太鸡肋&#xff0c;不值得消费者购买。 据悉iPhone15和iPhone15 plus将采用灵动岛设计&#x…

systrace: 系统级跟踪工具的解析

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、获取systrace文件3.1 通过python命令获取3.1.…

HCIP学习-ospf3

前置内容 HICA学习--ospf动态路由协议_板栗妖怪的博客-CSDN博客 HCIA学习--ospf配置_板栗妖怪的博客-CSDN博客 HCIP学习--ospf1_板栗妖怪的博客-CSDN博客 HICP学习--ospf2_板栗妖怪的博客-CSDN博客 5类、7类路由类型 概念 5、7类的路由会纯在一个类型1和类型2的区别 设备…

Jlink RTT工具打印日志

背景 平常调试代码中使用串口打印log&#xff0c;往往需要接出串口引脚&#xff0c;比较麻烦&#xff0c;并且串口打印速度较慢&#xff0c;串口的中断可能会影响代码的执行效率。 SEGGER RTT支持使用J-link调试器输出来自目标微控制器的信息&#xff0c;也可以接收输入&#…

Python 潮流周刊#15:如何分析异步任务的性能?

△点击上方“Python猫”关注 &#xff0c;回复“1”领取电子书 你好&#xff0c;我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容&#xff0c;大部分为英文。标题取自其中一则分享&#xff0c;不代表全部内容都是该主题&#xff0c;特此声明。 本周刊精心筛选国内外的…