数据结构笔记(其八)--一般树的存储及其遍历

news2024/11/16 6:16:30

1.知识总览

7e0e866cea694b068d411560e901c8be.png

        一般的树会有多个孩子,所以存储结构也会与二叉树略有不同。

        一般树的遍历。

2.双亲表示法

        双亲表示法,也是父亲表示法,即每个节点中都存储了其父节点的地址信息。

        特性:可以轻易地找到父节点,但寻找孩子节点麻烦。

        顺序储存,每个节点都储存有其对应的父节点数组下标,根节点默认为-1(且在顺序表中,只有下标为0,其内存有-1的节点是根结点)。

        i.代码

//定义树最多有多少节点
# define MAX 10
//定义树的节点
class PTNode
{
public:
    //数据元素
    int data;
    //父节点位置域
    int parent;
};
//定义树
class PTree
{
public:
    PTNode nodes[MAX];
    //指示当前节点个数
    int n;
};

        删除节点的思路:

        法一,将待删除节点储存的父节点下标设置为-1,意指该节点为空。

        法二,将数组最末尾的节点覆盖到待删除节点的位置,该法更优,可以保证前n个节点都是有意义的。

        在删除过程中,如果删除的节点还有孩子,那么,其实是在删除以它为根的子树,此时就需要查询到这个子树包含的所有节点,很显然,这需要非常麻烦的遍历,非必要不用顺序存储。

3.孩子表示法

        顺序+链式存储,用数组储存所有节点,在节点内部用链式结构储存与它直接相连的孩子节点下标(没有孩子的孩子,没有孙子辈的)。

        特性:找孩子简单,找父亲难。

        i.代码

//链表节点的结构
class CTNode
{
public:
    //孩子节点在数组中的位置
    int child;
    //下一个节点(下一个儿子,不是孙子)
    CTNode* next;
};
//包含链表的节点
class CTBox
{
public:
    //数据
    int data;
    //第一个孩子
    CTNode* firstChild;
};
//树
class CTree
{
public:
    CTBox nodes[MAX];
    //指示已有节点数和根节点的位置
    int n, r;
};

        同样也有一个弊端,就是难以找到双亲。

4.孩子兄弟表示法

        此法为链式存储,旨在把一般树转化为二叉树存储,这也是最重要的方法。

        节点中,有两个指针,一个指示自己的第一个孩子(是否有孩子),一个指示自己的兄弟(是否有兄弟)。

        通过这种遍历,就将一般树转化为二叉树存储

        i.代码

class CSNode
{
public:
    int data;
    //第一个孩子和右兄弟指针
    CSNode* firstchild,* nextbrother;
};
using CSTree = CSNode*;

        此法可以用来存储森林,每个树都转为二叉树,每个根节点都是平级的,可以看着兄弟结点。

5.树的先根遍历(深度优先遍历)

        先根:先访问根节点,再依次对子树进行先根遍历。

        在孩子兄弟表示法中,对一般树的先根遍历,与其对应的二叉树的先序遍历相同。

        代码中的部分内容会因为选择的存储结构的不同而有差异。

        i.代码

        以下,用孩子兄弟表示法作为存储结构,

class CSNode
{
public:
    int data;
    //第一个孩子和右兄弟指针
    CSNode* firstchild,* nextbrother;
};
using CSTree = CSNode*;

//先根遍历
void PreOrder(CSTree p)
{
    if (p != nullptr)
    {
        //访问(子树的)根节点
        visit(p);
        //如果该节点还有孩子,则去访问孩子
        if (p->firstchild != nullptr)
        {
            CSNode* n = p->firstchild;
            PreOrder(n);
        }
        //如果该节点还有兄弟,则再去访问
        if (p->nextbrother != nullptr)
        {
            CSNode* m = p->nextbrother;
            PreOrder(m);
        }
    }
}

6.树的后根遍历(深度优先遍历)

        后根:其逻辑与后序遍历类似,但是在孩子兄弟表示法中,出现了不同,一般树的后根遍历,与其对应的二叉树的中序遍历相同,这很反直觉。

        

7.树的层次遍历(广度优先遍历)

        即,逐层遍历,与二叉树的层序遍历逻辑基本相同,使用队列来辅助实现。

        · 队列为空,根节点入队

        · 队列非空,队头出队(并访问),同时队头如果有孩子,则其孩子依次入队。

        依次重复以上两个步骤,直到队列再次为空。

8.森林的先序遍历(中序遍历也是同理的)

        将森林转换为二叉树,再进行先序遍历,就是森林的先序遍历。

9.总结图

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

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

相关文章

Linux系统Centos设置开机默认root用户

目录 一. 教程 二. 部分第三方工具配置也无效 一. 教程 使用 Linux 安装Centos系统的小伙伴大概都知道,我们进入系统后,通常都是自己设置的普通用户身份,而不是 root 超级管理员用户,导致我们在操作文件夹时往往爆出没有权限&am…

医院信息化与智能化系统(21)

医院信息化与智能化系统(21) 这里只描述对应过程,和可能遇到的问题及解决办法以及对应的参考链接,并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图,可以试试PlantUML,告诉GPT你的文件结构,让他给你对应…

【论文阅读】利用SEM二维图像表征黏土矿物三维结构

导言 在油气储层研究中,黏土矿物对流体流动的影响需要在微观尺度上理解,但传统的二维SEM图像难以完整地表征三维孔隙结构。常规的三维成像技术如FIB-SEM(聚焦离子束扫描电子显微镜)虽然可以获取高精度的3D图像,但成本…

Yocto - 使用Yocto开发嵌入式Linux系统_13 创建定制层

Creating Custom Layers 除了使用社区或供应商提供的现有图层外,我们还将在本章中学习如何为我们的产品创建图层。此外,我们还将了解如何创建机器定义和分布,并从中获益,从而更好地组织我们的源代码。 In addition to using exist…

每日八股——JVM组成

直接上图 JVM(Java虚拟机)是运行Java字节码的虚拟机。它主要由以下几个部分组成: 1. 类加载器(ClassLoader) 负责加载class文件到内存中,并生成对应的Class对象。类加载器分为启动类加载器、扩展类加载器…

JavaScript 中的 undefined 、null 与 NaN :概念解析与对比

文章目录 💯前言💯undefined1. 什么是 undefined2. undefined 的使用场景3. undefined 的特性 💯null1. 什么是 null2. null 的使用场景3. null 的特性 💯NaN1. 什么是 NaN2. NaN 的使用场景3. NaN 的特性 💯三者的区别…

计算机网络学习笔记-3.3以太网和局域网

以太网 以太网(Ethernet)是一种用于计算机网络的技术规范,广泛应用于局域网(LAN)的构建。它定义了如何在网络设备之间传输数据,并确保这些数据能够被可靠传送。以太网是目前最常见和最广泛使用的局域网技术…

Linux篇(用户管理命令)

目录 一、用户与用户组 1. 为什么要做用户与用户组管理 2. Linux的用户及用户组 2.1. Linux的多用户多任务 2.2. 什么是用户 2.3. 什么是用户组 2.4. 用户和用户组的关系 二、用户和用户组管理 1. 用户组管理 1.1. 用户组添加 /etc/group文件结构 1.2. 用户组修改 …

2024-11-15 Element-ui的tab切换中table自适应宽度无法立即100%的问题

前言 今天在写一个统计图表的时候,将所有的table表格和echarts图表放到一个页面中,这样会在纵向上出现滚动条,上下滑动对用户体验不好,于是改成tab切换的形式 遇到的问题 正如标题所述,elementui在tab中使用table时&…

使用Git工具在GitHub的仓库中上传文件夹(超详细)

如何使用Git工具在GitHub的仓库中上传文件夹? 如果觉得博主写的还可以,点赞收藏关注噢~ 第一步:拥有一个本地的仓库 可以fork别人的仓库或者自己新创建 fork别人的仓库 或者自己创建一个仓库 按照要求填写完成后,点击按钮创建…

设计模式-Facade(门面模式)GO语言版本

前言 个人理解Facade模式其实日常生活中已经不知不觉就在使用了,基本核心内容就是暴露一些简单操作的接口,实现上将一些内容封装起来。 如上图,外界使用内部子系统时,只需要通过调用facade接口层面的功能,不需要了解子…

【隐私计算】隐私计算的应用场景探索(大模型隐私计算、隐私数据存储计算、Web3、隐私物联网等)

1. 背景分析 隐私计算作为一种实现“原始数据不出域,可用不可见”的数据流通价值的关键技术,经历了2020-2023年的高光时刻,却在2024年骤然走向低谷。从各种渠道了解到一些业内曾经风光无两的隐私计算公司都有不同程度的裁员。几乎一夜之间&am…

【提高篇】3.4 GPIO(四,工作模式详解 下)

四,模拟输入输出 上下拉电阻断开,施密特触发器关闭,双 MOS 管也关闭。该模式用于 ADC 采集或者 DAC 输出,或者低功耗下省电。但要注意的是 GPIO本身并不具备模拟输出输入的功能。 4.1 模拟输入 STM32内置ADC(模数转换器),可以将模拟信号转换为数字信号。GPIO引脚可以…

【青牛科技】D4147漏电保护电路介绍及应用

1、标题: D4147漏电保护电路 2、简介: 我司代理电源管理芯片,产品具有失效率低、可靠性高等特点。 3、具体应用: 相关产品介绍: 4、D4147 应用框图: D4147 方案介绍: 接地零线故障引起的接地…

【C++】深入理解自定义 list 容器中的 list_iterator:迭代器实现详解

个人主页: 起名字真南的CSDN博客 个人专栏: 【数据结构初阶】 📘 基础数据结构【C语言】 💻 C语言编程技巧【C】 🚀 进阶C【OJ题解】 📝 题解精讲 目录 📌 引言📌 1. 为什么 list 容器需要 list_iterator…

MuMu模拟器安卓12安装Xposed 框架

MuMu模拟器安卓12安装Xposed 框架 当开启代理后,客户端会对代理服务器证书与自身内置证书展开检测,只要检测出两者存在不一致的情况,客户端就会拒绝连接。正是这个原因,才致使我们既没有网络,又抓不到数据包。 解决方式: 通过xposed框架和trustmealready禁掉app里面校验…

MongoDB分布式集群搭建----副本集----PSS/PSA

MongoDB分布式集群 Replication 复制、Replica Set 复制集/副本集 概念 一、 副本集的相关概念 1.概念 “ A replica set is a group of mongod instances that maintain the same data set. ” 一组MongoDB服务器(多个mongod实例)(有不…

Java篇String类的常见方法

目录 一. String类的概念 1.1 String类的特性 二. 字符串的构造方式 三. 常用方法 3.1 字符串查找 3.2 字符串转换 3.3 字符串比较 3.3.1 equals( )方法 3.3.2 compare To( )方法 3.3.3 compare ToIgnoreCase( )方法 3.4 字符串替换 3.4.1 replace( )方法 3.4.2 r…

「QT」文件类 之 QDataStream 数据流类

✨博客主页何曾参静谧的博客📌文章专栏「QT」QT5程序设计📚全部专栏「Win」Windows程序设计「IDE」集成开发环境「UG/NX」BlockUI集合「C/C」C/C程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「UG/NX」NX定制…

MySQL45讲 第二十三讲 是怎么保证数据不丢的?

文章目录 MySQL45讲 第二十三讲 是怎么保证数据不丢的?一、binlog 写入机制(一)事务执行与 binlog cache(二)事务提交与 binlog 文件写入 二、redo log 写入机制(一)事务执行与 redo log buffer…