数据结构(五)——树森林

5.4 树和森林

5.4.1 树的存储结构

树的存储1:双亲表示法
用数组顺序存储各结点,每个结点中保存数据元素、指向双亲结点(父结点)的“指针”

#define MAX_TREE_SIZE 100

// 树的结点
typedef struct{
    ElemType data;
    int parent;
}PTNode;

// 树的类型
typedef struct{
    PTNode nodes[MAX_TREE_SIZE];
    int n;	//结点数量
}PTree;


优点:找双亲(父结点)很方便
缺点:找孩子不方便,只能从头到尾遍历整个数组

树的存储2:孩子表示法(顺序+链式存储)

#define MAX_TREE_SIZE 100

struct CTNode{
    int child;	//孩子结点在数组中的位置
    struct CTNode *next;	//下一个孩子
}

typedef struct{
    ElemType data;
    struct CTNode *firstChild;	//第一个孩子
}CTBox;

typedef struct{
    CTBox node[MAX_TREE_SIZE];
    int n,r;	//结点数和根的位置
}CTree;

优点:找孩子很方便
缺点:找双亲(父结点)不方便,只能遍历每个链表

树的存储3:孩子兄弟表示法
树的孩子兄弟表示法与二叉树类似,采用二叉链表实现,每个结点内保存数据元素和两个指针,但两个指针的含义和二叉树结点不同

//孩子兄弟表示法结点
typedef struct CSNode{
    ElemType data;
    struct CSNode *firstchild, *nextsibling;	//第一个孩子和右兄弟结点
}CSNode, *CSTree;

 

5.4.2 树、森林与二叉树的转换

树到二叉树的转换
①先在二叉树中,画一个根节点。
②按“树的层序”依次处理每个结点。
处理一个结点的方法是:如果当前处理的结点在树中有孩子,就把所有孩子结点 “用右指针串成糖葫芦”,并在二叉树中把第一个孩子挂在当前结点的左指针下方

森林到二叉树的转换
①先把所有树的根结点画出来,在二叉树中用右指针串成糖葫芦。
②按“森林的层序”依次处理每个结点。
处理一个结点的方法是:如果当前处理的结点在树中有孩子,就把所有孩子结点“用右 指针串成糖葫芦”,并在二叉树中把第一个孩子挂在当前结点的左指针下方

注意:森林中各棵树的根节点视为平级的兄弟关系

二叉树到树的转换
①先画出树的根节点
②从树的根节点开始,按“树的层序”恢复每个结点的孩子
如何恢复一个结点的孩子:在二叉树中,如果当前处理的结点有左孩子,就把左孩 子和“一整串右指针糖葫芦” 拆下来,按顺序挂在当前结点的下方


二叉树到森林的转换
①先把二叉树的根节点和“一整串右指针糖葫芦”拆下来,作为多棵树的根节点
②按“森林的层序”恢复每个结点的孩子
如何恢复一个结点的孩子:在二叉树中,如果当前处理的结点有左孩子,就把左孩子和“一整串右指针糖葫 芦” 拆下来,按顺序挂在当前结点的下方


5.4.3 树和森林的遍历

树的先根遍历。若树非空,先访问根结点, 再依次对每棵子树进行先根遍历。(深度优先遍历)

void PreOrder(TreeNode *R){
    if(R!=NULL){
        visit(R);
        while(R还有下一个子树T)
            PreOrder(T);
    }
}

树的先根遍历序列与这棵树相应二叉树的先序序列相同

树的后根遍历。若树非空,先依次对每棵子树进行后根遍历,最后再访问根结点。(深度优先遍历)

树的后根遍历序列与这棵树相应二叉树的中序序列相同。

树的层次遍历(用队列实现):(广度优先遍历)
   ①若树非空,则根节点入队
   ②若队列非空,队头元素出队并访问,同时将该元素的孩子依次入队
   ③重复②直到队列为空

森林的先序遍历
森林。森林是m (m>0)棵互不相交的树的集合。每棵树去掉根节点后,其各个子树又组成森林。

若森林为非空,则按如下规则进行遍历:

  1. 访问森林中第一棵树的根结点。
  2. 先序遍历第一棵树中根结点的子树森林。
  3. 先序遍历除去第一棵树之后剩余的树构成的森林。

效果等同于依次对各个树进行先根遍历,等同于对二叉树的先序遍历。

森林的中序遍历

  1. 中序遍历森林中第一棵树的根结点的子树森林。
  2. 访问第一棵树的根结点。
  3. 中序遍历除去第一棵树之后剩余的树构成的森林

效果等同于依次对各个树进行后根遍历,等同于对二叉树的中序遍历。

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

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

相关文章

学习或复习电路的game推荐:nandgame(NAND与非门游戏)、Turing_Complete(图灵完备)

https://www.nandgame.com/ 免费 https://store.steampowered.com/app/1444480/Turing_Complete/ 收费,70元。据说可以导出 Verilog !

关于安卓调用文件浏览器(一)打开并复制

背景 最近在做一个硬件产品,安卓应用开发。PM抽风,要求从app打开文件浏览器,跳转到指定目录,然后可以实现文件复制粘贴操作。 思考 从应用开发的角度看,从app打开系统文件浏览器并且选择文件,这是很常见…

馆室一体化查档平台制度有哪些

馆室一体化查档平台制度是指图书馆或档案馆在数字化和信息化的背景下,建立起的集查阅、借阅、咨询、文献传递等多项功能于一体的平台制度。下面是一些常见的馆室一体化查档平台制度: 1. 馆藏管理制度:包括图书和档案的采购、编目、分类、整理…

那些王道书里的题目-----计算机网络篇

注:仅记录个人认为有启发的题目 p155 34.下列四个地址块中,与地址块 172.16.166.192/26 不重叠,且与172.16.166.192/26聚合后的地址块不会引入多余地址的是() A.172.16.166.192/27 B.172.16.166.128/26 …

day06vue2学习

day06 路由的封装抽离 问题:所有的路由配置都堆在main.js中不太合适么?不好,会加大代码的复杂度 目标:将路由模块抽离出来。好处:差分模块,利于维护。 大致的做法就是,将路由相关的东西都提…

codeTop102:二叉树的层序遍历

前言 在已知BFS的方式后,知道每次从队列中取一个节点,就要将这个节点的所有子节点按照顺序放入队列。 难点在于怎么确定将同一层的节点放在一个数组里面的输出,也就是输出一个二维数组? 解决方法: 每次while循环将队列上轮放入的…

蓝桥集训之矩形牛棚

蓝桥集训之矩形牛棚 核心思想&#xff1a;单调队列 模板&#xff1a;Acwing.131.直方图矩形面积首先遍历所有下界 然后确定以该下界为底的直方图 求最大矩形 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 30…

Java学习day2

命名规则 在JAVA中&#xff0c;公共类的明朝必须与包含该类的源文件的文件名向匹配&#xff0c;即 这两个名称要一致 变量类型 与c/c基本一致 需要注意的是&#xff0c;long类型的数据在后面需要加上l或L&#xff08;建议加L&#xff0c;l可能会被误判&#xff09;&#xff…

【Redis】优惠券秒杀

全局唯一ID 全局唯一ID生成策略&#xff1a; UUIDRedis自增snowflake算法数据库自增 Redis自增ID策略&#xff1a;每天一个key&#xff0c;方便统计订单量ID构造是 时间戳 计数器 Component public class RedisIdWorker {// 2024的第一时刻private static final long BEGIN…

【C语言】编译和链接----预处理详解【图文详解】

欢迎来CILMY23的博客喔&#xff0c;本篇为【C语言】文件操作揭秘&#xff1a;C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】&#xff0c;感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞关注收藏。 前言 欢迎来到本篇博客&…

易语言学习第一天(安装破解和配置)

一、引言 易语言是一个自主开发&#xff0c;适合国情&#xff0c;不同层次不同专业的人员易学易用的汉语编程语言。易语言降低了广大电脑用户编程的门槛&#xff0c;尤其是根本不懂英文或者英文了解很少的用户&#xff0c;可以通过使用本语言极其快速地进入Windows程序编写的大…

全新的分布式锁,功能简单且强大

分布式锁是分布式系统中一个极为重要的工具。 目前有多种分布式锁的设计方案&#xff0c;比如借助 redis&#xff0c;mq&#xff0c;数据库&#xff0c;zookeeper 等第三方服务系统来设计分布式锁。 tldb 提供的分布式锁&#xff0c;主要是要简化这个设计的过程&#xff0c;提…

安全之剑:深度解析 Apache Shiro 框架原理与使用指南

在现代软件开发中&#xff0c;安全性一直是至关重要的一个方面。随着网络攻击和数据泄露的不断增加&#xff0c;我们迫切需要一种强大而灵活的安全框架来保护我们的应用。Shiro框架就是这样一把利剑&#xff0c;它能够轻松地集成到你的项目中&#xff0c;为你的应用提供可靠的安…

用户增长的底层逻辑:从原理到实践

在互联网行业的洪流中&#xff0c;用户增长被视为企业生命力与竞争力的重要标志。理解并掌握用户增长的底层逻辑&#xff0c;是每一位产品经理、市场营销人员以及创业者不可或缺的基本功。 用户增长的底层逻辑&#xff1a;从原理到实践© 由 ZAKER科技 提供 一、用户增长的…

02.percona Toolkit工具pt-archiver命令实践

1.命令作用 Percona Toolkit有的32个命令&#xff0c;可以分为7大类 工具类别 工具命令 工具作用 备注 开发类 pt-duplicate-key-checker 列出并删除重复的索引和外键 pt-online-schema-change 在线修改表结构 pt-query-advisor 分析查询语句&#xff0c;并给出建议&#x…

深度学习知识点:神经网络

深度学习知识点&#xff1a;神经网络 前言神经网络激活函数的优缺点为什么ReLU常用于神经网络的激活函数&#xff1f;梯度消失和梯度爆炸的解决方案&#xff1f;梯度爆炸引发的问题&#xff1f;如何确定是否出现梯度爆炸&#xff1f;神经网络中有哪些正则化技术&#xff1f;批量…

知识图表示学习中的负抽样研究综述

摘要 知识图表示学习(KGRL)或知识图嵌入(KGE)在知识构建和信息探索的人工智能应用中起着至关重要的作用。这些模型旨在将知识图中的实体和关系编码到低维向量空间中。在KGE模型的训练过程中&#xff0c;使用正样本和负样本是区分的必要条件。然而&#xff0c;直接从现有的知识…

Qt 写一个邮件发送程序

最近在完成一个邮箱代替的告警功能&#xff0c;写了一个邮件发送的demo 以下为代码&#xff1a; #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include<QTcpSocket> namespace Ui { class MainWindow; }class MainWindow : public QMainWin…

C语言字节对齐关键字#pragma pack(n)的使用

0 前言 在进行嵌入式开发的过程中&#xff0c;我们经常会见到对齐操作。这些对齐操作有些是为了便于实现指针操作&#xff0c;有些是为了加速对内存的访问。因此&#xff0c;学习如何使用对齐关键字是对于嵌入式开发是很有必要的。 1 对齐规则 1.0 什么叫做对齐 众所周知&a…

深度学习pytorch——多层感知机反向传播(持续更新)

在讲解多层感知机反向传播之前&#xff0c;先来回顾一下多输出感知机的问题&#xff0c;下图是一个多输出感知机模型&#xff1a; 课时44 反向传播算法-1_哔哩哔哩_bilibili 根据上一次的分析深度学习pytorch——感知机&#xff08;Perceptron&#xff09;&#xff08;持续更新…