【数据结构】4——树和森林

news2024/11/22 22:46:10

数据结构——4树和森林

笔记


文章目录

  • 数据结构——4树和森林
  • 树的存储结构
    • 双亲表示法
    • 孩子链表
    • 孩子兄弟表示法(二叉树表示法、二叉链表表示法)
  • 树与二叉树转换
  • 森林和二叉树转化
    • 森林转二叉树
    • 二叉树转森林
  • 树和森林的遍历
      • 先根
      • 后根
      • 层次
    • 森林


树的存储结构

双亲表示法

每个节点只存储其父节点的引用或索引

通常使用数组来存储树中所有节点的信息,数组的每个元素对应一个节点,数组的索引通常从0或1开始。对于数组中的任意元素(即某个节点),其值表示该节点的双亲节点在数组中的位置(索引)。如果某个节点是根节点,则其双亲位置通常用-1或null表示,以表示它没有双亲节点。

节点结构:每个节点通常包含数据部分和指向其父节点的引用或索引。节点的数据部分可以是任何类型的信息,而父节点的引用可以是节点在数组中的索引,也可以是指向父节点的指针。
存储方式:整个树结构存储在一个数组(或类似的数据结构)中。根节点通常在数组的第一个位置(或者索引为0的位置),其父节点的引用为空或为一个特定的标识(如-1),表示它没有父节点。
遍历能力:通过双亲表示法可以方便地找到任意节点的父节点,但要找到某个节点的所有子节点则需要遍历整个数组,效率较低。
空间利用:这种表示法不需要额外的空间来存储子节点的信息,因此在空间利用上相对高效。


       A
     / | \
    B  C  D
   / \
  E   F
  
从索引 1 开始
索引:      1  2  3  4  5  6
节点:      A  B  C  D  E  F
双亲索引: -1  1  1  1  2  2

节点 A 的双亲索引是 -1,表示它是根节点。
节点 B、C、D 的双亲索引都是 1,表示它们的双亲是节点 A。
节点 E 的双亲索引是 2,表示它的双亲是节点 B,以此类推。


//查找节点 E 的双亲节点:
从数组中找到索引为 5 的元素,其值为 2,表示节点 E 的双亲节点是索引为 2 的节点,即节点 C。

孩子链表

每个节点除了存储其数据之外,还包含一个指向其所有子节点的链表。

节点结构:每个节点包含数据部分和指向其第一个子节点的指针。如果节点没有子节点,则该指针为空。
子节点链表:每个节点可能有一个链表,链表的每个节点代表其一个子节点。链表的每个节点通常包含指向子节点的指针和指向下一个子节点链表节点的指针。
遍历能力:孩子链表结构便于遍历树的子节点,可以方便地访问任何节点的所有直接子节点。
空间利用:孩子链表结构需要额外的空间来存储子节点链表的指针,因此相对于双亲表示法,它可能占用更多的空间。
灵活性:这种表示法可以很容易地表示动态变化的树结构,如二叉查找树的插入和删除操作。

        A
       / \
      B   C
     / \
    D   E

伪代码
节点A:
    value = "A"
    first_child = 节点B
    next_sibling = None

节点B:
    value = "B"
    first_child = 节点D
    next_sibling = 节点C

节点C:
    value = "C"
    first_child = None
    next_sibling = None

节点D:
    value = "D"
    first_child = None
    next_sibling = 节点E

节点E:
    value = "E"
    first_child = None
    next_sibling = None

孩子兄弟表示法(二叉树表示法、二叉链表表示法)

基本原理:
在孩子兄弟表示法中,每个节点包含三个部分:

数据域:存储该节点的数据信息。
第一个孩子指针:指向该节点的第一个孩子节点。
下一个兄弟指针:指向该节点的下一个兄弟节点。

通过这种方式,树中的每个节点可以通过其孩子指针找到它的所有孩子节点,通过兄弟指针找到它的所有兄弟节点。这样就可以方便地遍历整棵树。

找双亲比较难

假设有一棵树如下:
     O
   / |  \
  P  Q   R
 / \ /
S  T U
|
V
用孩子兄弟表示法表示为:
节点 O:数据为 O,第一个孩子为节点 P,下一个兄弟为 null。
节点 P:数据为 P,第一个孩子为节点 S,下一个兄弟为节点 Q。
节点 Q:数据为 Q,第一个孩子为 null,下一个兄弟为节点 R。
节点 R:数据为 R,第一个孩子为节点 U,下一个兄弟为 null。
节点 S:数据为 S,第一个孩子为 null,下一个兄弟为节点 T。
节点 T:数据为 T,第一个孩子为 null,下一个兄弟为 null。
节点 U:数据为 U,第一个孩子为节点 V,下一个兄弟为 null。
节点 V:数据为 V,第一个孩子为 null,下一个兄弟为 null。

树与二叉树转换

树转换为二叉树的方法:
加线:在兄弟之间加一条连线。
抹线:对每个节点,除了其左孩子外,去除其与其余孩子之间的连线。
旋转:以树的根结点为轴心,将整棵树顺时针旋转45度。
左(第一个)孩子右兄弟

       A
     / | \
    B  C  D
   / \     \
  E   F     G

根节点 A 的第一个子节点 B 作为它的左孩子。
B 的第一个子节点 E 作为它的左孩子,C 是 B 的兄弟,因此在二叉树中作为 B 的右孩子。
E 的兄弟 F 作为它的右孩子。
C 没有子节点,但它有兄弟 D,所以 D 作为 C 的右孩子。
D 的第一个子节点 G 作为它的左孩子。
       A
      /
     B
    / \
   E   C
    \   \
     F   D
         /
        G


二叉树转换为树的方法为:
加线:若某结点的左孩子结点存在,则将这个左孩子的右孩子结点、右孩子的右孩子结点……都与该结点用线连接起来。
抹线:抹掉原二叉树中所有结点与其右孩子结点的连线。
调整:使各结点按层次排列,形成树结构。

原先在二叉树中的左孩子表示多叉树中的第一个子节点,而右兄弟则表示多叉树中的后续子节点。

    A
   /
  B
 / \
E   C
 \   \
  F   D
和上面相反,右孩子是兄弟
    A
   /|\
  B C D
 / \
E   F


森林和二叉树转化

森林转二叉树

选择一棵根树:从森林中选择一棵树作为新二叉树的根。这棵树将成为二叉树的根节点。
连接其他树:将森林中的其他树依次连接到选定的根树的右侧。为了做到这一点,可以将每棵树的根节点作为上一棵树的根节点的右子节点。
调整结构:如果需要,调整树的结构以确保它符合二叉树的定义。这可能包括重新排列节点以保持正确的顺序或平衡。

在这里插入图片描述

二叉树转森林

去右孩线,二叉树转树
在这里插入图片描述

树和森林的遍历

先根

    A
   / \
  B   C
 / \   \
D   E   F

访问根节点 A。
遍历左子树:
访问左子树的根节点 B。
遍历 B 的左子树:
访问 D。
遍历 B 的右子树:
访问 E。
遍历右子树:
访问右子树的根节点 C。
遍历 C 的左子树(为空,跳过)。
遍历 C 的右子树:
访问 F

A -> B -> D -> E -> C -> F

后根

      A
     / \
    B   C
   / \
  D   E
  
递归遍历左子树 B
递归遍历左子树 D,访问 D
递归遍历右子树 E,访问 E
回到 B,访问 B
递归遍历右子树 C,访问 C
回到根节点 A,访问 A

D E B C A

层次

    A
   / \
  B   C
 / \   \
D   E   F

A B C D E F 

森林

Tree 1:      Tree 2:       Tree 3:
    A           F             K
   / \         / \           / \
  B   C       G   H         L   M
     /             \
    D               I

前序遍历结果:
Tree 1: A B C D
Tree 2: F G H I
Tree 3: K L M
森林的前序遍历整体结果:A B C D F G H I K L M

中序遍历结果:
Tree 1: B A D C
Tree 2: G F H I
Tree 3: L K M
森林的中序遍历整体结果:B A D C G F H I L K M

后序遍历结果:
Tree 1: B D C A
Tree 2: G I H F
Tree 3: L M K
森林的后序遍历整体结果:B D C A G I H F L M K

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

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

相关文章

使用nvm工具实现多个nodejs版本的维护和切换

NodeJS的升级比较快,在开发中要使用最新的版本,必须经常升级,但对于一些老项目可能又要使用低版本的NodeJS,虽然可以在系统中同时安装多个NodeJS的版本,然后通过修改环境变量的方式实现切换,但这种方法太麻…

断点回归模型

断点回归(Regression Discontinuity Design, RDD)是一种准实验设计方法,用于评估政策或其他干预措施的效果。这种方法利用了一个清晰的阈值或“断点”,在这个阈值上,处理状态(例如是否接受某种干预&#xf…

浅谈为什么数据库要用B树

朋友,你有没有遇到过这样的情况?明明数据库里存的东西还不算太多,可一查数据,页面加载慢得像蜗牛?别急,问题可能出在你的数据库索引上。而今天我要跟你聊的,就是在数据库里被广泛应用的B树(B-Trees),它可是提升数据库性能的秘密武器。听起来有点深奥?别担心,我会用…

C程序设计——再说说函数参数的值传递

上一篇的最后,我强调了C语言里,所有函数参数的传递,都是值传递,即形参值改变,不影响实参的值。 指针作为函数参数 我们知道,指针也是C语言的一个类型,所以指针,也可以作为函数参数…

【TPAMI 2024】一种用于混合事件-帧摄像机的异步线性滤波器架构

题目:An Asynchronous Linear Filter Architecture for Hybrid Event-Frame Cameras 一种用于混合事件-帧摄像机的异步线性滤波器架构 作者:Ziwei Wang; Yonhon Ng; Cedric Scheerlinck; Robert Mahony 摘要 事件相机非常适合捕捉高动态范围(HDR)视觉…

运维保障高效化的智慧能源开源了

一、简介 AI视频监控平台, 是一款功能强大且简单易用的实时算法视频监控系统。愿景在最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,减少企业级应用约 95%的开发成本,在强大视频算…

【python因果推断库13】使用 PyMC 模型进行回归断点分析

目录 线性模型、主效应模型和交互作用模型 使用bandwidth 使用基样条 import causalpy as cp %load_ext autoreload %autoreload 2 %config InlineBackend.figure_format retina seed 42 df cp.load_data("rd") 线性模型、主效应模型和交互作用模型 PyMC 采样…

教学辅助微信小程序|基于SSM+vue的高校教学微信小程序系统(源码+数据库+文档)

高校教学 目录 基于SSM教学辅助微信小程序 一、前言 二、系统设计 三、系统功能设计 小程序端 后台功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师&#x…

【Python】01.Python 介绍及其环境配置

一、计算机的基础概念 1.1 什么是计算机 所谓计算机,不光能进行算术运算,还能进行逻辑判断、数据存储、网络通信等等功能,以至于可以自动的完成非常复杂的工作。以下这些都可以称为 “计算机” : 1.2 冯诺依曼体系结构 而一台…

媒体服务器软件BUG说明及改进方案

媒体服务器软件BUG说明及改进方案 一、BUG描述二、问题分析三、改进方案四、实施计划五、预期效果六、总结一、BUG描述 在当前版本的媒体服务器中,存在一个关于静音媒体流处理的问题。具体表现为:当主叫连续发送静音帧到媒体服务器时,媒体服务器并未将这些静音帧转发给被叫…

闯关leetcode——13. Roman to Integer

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/roman-to-integer/description/ 内容 Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. SymbolValueI1V5X10L50C100D500M1000 For example, 2 is written …

CVE-2024-37032-Ollama漏洞

简介 Ollama是一个专为在本地环境中运行和定制大型语言模型而设计的工具。它提供了一个简单高效的接口,用于创建、运行和管理这些模型,同时还提供了一个丰富的预构建模型库,可以轻松集成到各种应用程序中。Ollama的目标是使大型语言模型的部…

Redis——初识Redis

初识Redis Redis认识Redis 分布式系统单机架构为什么要引入分布式理解负载均衡数据库的读写分离引入主从数据库 引入缓存数据库分库分表业务拆分——微服务常见概念了解 Redis背景介绍特性应用场景Redis不能做的事情Redis客户端redis客户端的多种形态 Redis 认识Redis 存储数…

flow model

https://www.youtube.com/watch?vuXY18nzdSsMcomponent by component(auto regresive)的生成模型存在的问题(生成的顺序,生成的速度慢);variational auto-encoder存在的问题(optimize a maxihood lower bound,是一个近似);genera…

【机器学习】隐马尔可夫模型的基本概念和应用领域以及在NLP中如何实现(含python代码)

引言 隐马尔可夫模型(Hidden Markov Model,HMM)是一种统计模型,用于描述一个含有隐含状态的马尔可夫过程 文章目录 引言一、隐马尔可夫模型的基本概念1.1 HMM的基本组成1.2 HMM的三个基本问题1.3 解决HMM问题的算法1.4 在python中…

Linux 安装神州通用数据库 ShenTong7.0.8_342.92_linux64

Linux 安装神州通用数据库 ShenTong7.0.8_342.92_linux64 1、准备工作2、安装数据库3、启停数据库4、后续步骤 💖The Begin💖点点关注,收藏不迷路💖 在Linux环境下安装神州通用数据库(ShenTong)是一个相对直…

如何通过 Apache Camel 将数据导入 Elasticsearch

作者:来自 Elastic Andre Luiz 使用 Apache Camel 将数据提取到 Elasticsearch 的过程将搜索引擎的稳健性与集成框架的灵活性相结合。在本文中,我们将探讨 Apache Camel 如何简化和优化将数据提取到 Elasticsearch。为了说明此功能,我们将实…

5G网络建设

题目描述 现需要在基城市进行5G网络建设,已经选取N个地点设置5G基站,编号固定为1到N,接下来需要各个基站之间使用光纤进行连接以确保基 站能互联互通,不同基站之间假设光纤的成本各不相同,且有些节点之间已经存在光纤…

8个动态着陆页案例及最佳实践

动态着陆页是一种让市场营销人员在不必因成百上千变量而抓狂的情况下,利用个性化力量的绝佳方式,从而让他们能够扩大努力并增长业务。使用像光年AI这样的平台,可以更方便地实现这一目标。 在这篇文章中,您将了解到: …

非监督式机器学习:群集

聚类分析是一种非监督式机器学习形式,在此形式下,基于观察值的数据值或特征的相似性,将观察值分组到群集中。 这种就是非监督式机器学习,因为它不使用先前已知的标签值来训练模型。 在聚类分析模型中,标签是群集&#…