【数据结构】树与森林(树的存储结构、森林与二叉树的转化、树与森林的遍历)

目录

  • 树和森林
    • 树的存储结构
      • 一、树的双亲表示法:
      • 二、树的孩子表示法
        • 方法一:定长结点的多重链表
        • 方法二:不定长结点的多重链表
        • 方法三:孩子单链表表示法
      • 三、树的二叉链表(孩子-兄弟)存储表示法
    • 森林与二叉树的转换
    • 树和森林的遍历
      • 先根(次序)遍历
      • 后根(次序)遍历(待补充)
      • 按层次遍历(待补充)

  1. 树与二叉树知识点文章: 【数据结构】树与二叉树(递归法先序、中序、后序、层次遍历二叉树、二叉树的建立以及求树高的方法)
  2. 二叉树遍历算法的应用: 【数据结构】树与二叉树遍历算法的应用(求叶子节点个数、求树高、复制二叉树、创建二叉树、二叉树存放表达式、交换二叉树每个结点的左右孩子)

树和森林

树的非顺序存储映像:

  1. 双亲表示法
  2. 孩子表示法
  3. 树的二叉链表(孩子-兄弟)存储表示法

树的存储结构

一、树的双亲表示法:

祖先(双亲)
定义:用一维数组存放树中的每一结点的值(data)和双亲位置(parent,逻辑关系)

特点:找祖先易,找子孙难
典型用例:并查集
在这里插入图片描述

//树的双亲表示法
#define MAX_TREE_SIZE 100
typedef struct PTNode {
    int data;
    int parent;  // 双亲位置
} PTNode;

typedef struct {
    PTNode nodes[MAX_TREE_SIZE];
    int  r,n;//r为根节点的位置,n为树中结点的个数
} PTree;

说明:结点存放无顺序要求,根结点不一定存在第一个位置;每个数组元素对应树中一个结点,存放结点的值和双亲位置r—根结点位置,n—树中结点个数。

二、树的孩子表示法

树的孩子表示法:存放树中每个结点的信息、直接后继的地址。

根据结点直接后继的存放方式,分为:

  1. 定长结点的多重链表:每个结点按照树的度设置孩子指针的数量
  2. 不定长结点的多重链表:每个结点按照结点自身的度设置孩子指针的数量
  3. 孩子单链表:每个结点的孩子结点(直接后继)建一个单链表
方法一:定长结点的多重链表

树的孩子表示法:定长结点的多重链表
(典型:实现树的层次遍历)

定义:链表存放树中的每一结点的值(data)和孩子结点位置(child[i],第i个孩子指针,表示逻辑关系),每个结点的孩子指针的个数=树中孩子最多的结点的孩子个数=树的度.
在这里插入图片描述

1. 特点:结点的结构统一,若树的度为d,则点包含一个数据域,d个孩子指针域.

2. 缺点:空指针多,浪费空间

方法二:不定长结点的多重链表

树的孩子表示法–不定长结点的多重链表

定义:链表存放树中的每一结点的值(data)和孩子结点位置(child[i],逻辑关系),每个结点的孩子指针的个数=该结点的孩子个数=结点的度
在这里插入图片描述

树的度为d,该树的不定长结点的多重链表中结点结构有几种?
树的度为d=3,该树的不定长结点的多重链表中结点结构有4种
总结:树的度为d,该树的不定长结点的多重链表中结点结构有d+1种.

在这里插入图片描述

特点:结点的结构不统一,包含一个数据域,结点的度d, d个孩子指针域
缺点:操作较复杂

方法三:孩子单链表表示法

将每个结点的孩子结点拉成一个单链表
情况一:
结点C在孩子表示法中存了2次
一次出现在下标为2的数组元素中,该数组元素同时保存了C的孩子单链表的头指针。
一次出现在结点A的孩子单链表中。
数据元素存放多次更新操作比较麻烦,更新一个数据元素,所有保存该数据元素的地方均要更新,否则信息不一致

在这里插入图片描述

情况二:
节省存储空间方便更新操作和数据维护,每个数据元素只在数组中存放一次;
在孩子单链表中只存放这个孩子在数组中的位置
如下图所示:
结点A的孩子单链表中第一个孩子结点是下标为1的数组元素(B),第二个孩子是下标为2的数组元素(C),第三个孩子是下标为3的数组元素(D)。
在这里插入图片描述

若既要找子孙,又要找祖先,可将孩子单链表和双亲表示法结合在一起每个数组元素的data域存放数据元素的值,pa域存放双亲结点在数组中的位置,firstchild存其孩子单链表的头指针。
在这里插入图片描述

typedef struct CTNode{ 
    int child;
    struct CTNode *next;
 } *ChildPtr;

//数组元素类型:
typedef struct{ 
    ElemType  data; 
    ChildPtr firstchild;
//孩子单链表的头指针
} CTBox;

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

三、树的二叉链表(孩子-兄弟)存储表示法

[fc,data,nb]
在这里插入图片描述

typedef struct CSNode{
    int data;
    struct CSNode *fc, *nb;
}CSNode, *CSTree;

树中每个结点三部分:
数据域(data),长子指针域(fc),
右邻兄弟指针域(nb)

树和二叉树的转换
• 树以孩子兄弟表示法存,相当于将树转换成二叉树,但此二叉树根结点无右子树
• 好处:借助二叉树的操作实现树的操作

森林与二叉树的转换

⮚ 树采用二叉链表(孩子-兄弟)存储表示法,转换成二叉树
⮚ 森林由多棵树组成: F = ( T 1 , T 2 , … , T n ) F = ( T1, T2, …, Tn ) F=(T1,T2,,Tn); 将其每棵树转换成二叉树 B T 1 , B T 2 , … , B T n BT₁, BT₂, …, BTn BT1,BT2,,BTn;
⮚ 每棵二叉树BT的根的右子树皆为空树,从BTn开始依次将其根结点链为前一棵二叉树的根的右孩子
⮚ 将森林转换成一棵二叉树,森林的操作可借助二叉树的操作完成

森林和二叉树的转换
• 森林以孩子兄弟表示法存,相当于将森林转换成二叉树
• 好处:借助二叉树的操作实现森林的操作

树和森林的遍历

■ 树的遍历可有三条搜索路径:
⮚ 先根(次序)遍历:若树不空,则先访问根结点,然后依次先根遍历各棵子树。
⮚ 后根(次序)遍历:若树不空,则先依次后根遍历各棵子树,然后访问根结点。
⮚ 按层次遍历:若树不空,则自上而下自左至右访问树中每个结点。
在这里插入图片描述

[fc,data,nb]

typedef structCSNode{
    int data;
    structCSNode*fc, *nb;
}CSNode, *CSTree;

树中每个结点三部分:数据域(data),长子指针域(fc),右邻兄弟指针域(nb)

先根(次序)遍历

对应二叉树的先序

//树的孩子兄弟表示法
typedef structCSNode{
    ElemType data;
    structCSNode*fc, *nb;
}CSNode, *CSTree;

//二叉树的二叉链表表示法
typedef struct BiTNode {
    ElemType  data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

void PreorderTraverse(CSTree T){
	SeqStack s ;	
	s.top=-1; 
	p = T;
	while(p){
		while(p){
			printf(%c”,p->data);
			if(p->nb)
				if(s.top==MAX-1) exit (0);
				else s.data[++s.top]=p->nb;
			p =p->fc;
		}
		if (s.top!=-1) p=s.data[s.top--];
	}
}

后根(次序)遍历(待补充)

对应二叉树的中序

按层次遍历(待补充)

叶子结点
判断是否为子孩子 fc是否为空
p->fc == NULL

森林由三部分构成:
1.森林中第一棵树的根结点;
2.森林中第一棵树的子树森林;
3.森林中其它树构成的森林。

  1. 后根(次序)遍历与对应的二叉树的中序遍历相同
  2. 先根(次序)遍历与对应的二叉树的先序遍历相同
  3. 森林的先序遍历—对应二叉树的先序遍历
  4. 森林的中序遍历—对应二叉树的中序遍历

感谢阅读!!!

  1. 树与二叉树知识点文章: 【数据结构】树与二叉树(递归法先序、中序、后序、层次遍历二叉树、二叉树的建立以及求树高的方法)
  2. 二叉树遍历算法的应用: 【数据结构】树与二叉树遍历算法的应用(求叶子节点个数、求树高、复制二叉树、创建二叉树、二叉树存放表达式、交换二叉树每个结点的左右孩子)

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

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

相关文章

Java中的容器

Java中的容器主要包括以下几类: Collection接口及其子接口/实现类: List 接口及其实现类: ArrayList:基于动态数组实现的列表,支持随机访问,插入和删除元素可能导致大量元素移动。LinkedList:基…

前端常见面试题:HTML+CSS

1. title与h1的区别、b与strong的区别、i与em的区别? title与h1的区别: title标签用于定义整个HTML文档的标题,它显示在浏览器窗口的标题栏或者标签页上。每个HTML文档只应该有一个title标签,它对搜索引擎优化(SEO&a…

C语言结构体与公用体

结构体 概述 有时我们需要将不同类型的数据组合成一个有机的整体,如:一个学生有学号/姓名/性别/年龄/地址等属性这时候可通过结构体实现结构体(struct)可以理解为用户自定义的特殊的复合的“数据类型” 可以理解为其他语言的object类型 结构体变量的定…

项目五:学会如何使用python爬虫解析库(小白小成级)

前言 在上一篇我们学习了re模块的使用方法和了解正则表达式的基本语法规则,那么这一次还继续在学习一下re模块的函数用法,毕竟要想短时间内学会爬虫,基本功一定要扎实。这样面对日益更新的技术我们能够从容应对。 当然忘了可以看一下下面的…

使用SpringBoot将中国地震台网数据保存PostGIS数据库实践

目录 前言 一、数据转换 1、Json转JavaBean 2、JavaBean与数据库字段映射 二、空间数据表设计 1、表结构设计 三、PostGIS数据保存 1、Mapper接口定义 2、Service逻辑层实现 3、数据入库 4、运行实例及结果 总结 前言 在上一篇博客中基于Java的XxlCrawler网络信息爬…

ActiveMQ 07 集群配置

Active MQ 07 集群配置 官方文档 http://activemq.apache.org/clustering 主备集群 http://activemq.apache.org/masterslave.html Master Slave TypeRequirementsProsConsShared File System Master SlaveA shared file system such as a SANRun as many slaves as requ…

leetcode:739.每日温度/496.下一个更大元素

单调栈的应用: 求解当前元素右边比该元素大的第一个元素(左右、大小都可以)。 单调栈的构成: 单调栈里存储数组的下标; 单调栈里的元素递增,求解当前元素右边比该元素大的第一个元素;元素递…

Python继承

语法格式: class 子类类名(父类1[,父类2,...]):类体如果在类定义中没有指定父类,则默认父类是 object类 。也就是说,object 是所有类的父类,里面定义了一些所有类共有的默认实现,比…

Python接口自动化 —— Web接口!

1.2.1 web接口的概念 这里用一个浏览器调试工具捕捉课程管理页面请求作为例子: 当请求页面时,服务器会返回资源,将协议看做是路的话,http可以看做高速公路,soap看做铁路传输的数据有html,css&#xff0…

【文献分享】PCCP:机器学习 + 分子动力学 + 第一性原理 + 热学性质 + 微观结构

分享一篇关于机器学习 分子动力学 第一性原理 热学性质(密度、粘度、扩散系数) 微观结构的文章。 感谢论文的原作者! 关键词: 1. Machine learning, 2. Deep potential, 3. Molecular dynamics 4. Molten salt, 5. Thermo…

OCP-数据库中的小米SU7

oracle ocp ​数据库中的SU7 ​好看又好用 需要找工作和落户的快来

剑指offer剪绳子;leetcode:LCR 131. 砍竹子 I

现需要将一根长为正整数 bamboo_len 的竹子砍为若干段&#xff0c;每段长度均为正整数。请返回每段竹子长度的最大乘积是多少。 示例 1&#xff1a; 输入: bamboo_len 12 输出: 81提示&#xff1a; 2 < bamboo_len < 58 注意&#xff1a;本题与主站 343 题相同&#…

基于峰谷分时电价引导下的电动汽车充电负荷优化

在研究电动汽车用户充电需求的前提下&#xff0c;利用蒙特卡洛方法对&#xff12;种不同充电方式进行模拟并对其进行分 析&#xff1b;分析用户响应度对电动汽车有序充电的影响&#xff0c;建立峰谷分时电价对电动汽车负荷影响的模型&#xff0c;在模拟出电动汽 车无序充电负荷…

Windows 部署ChatGLM3大语言模型

一、环境要求 硬件 内存&#xff1a;> 16GB 显存: > 13GB&#xff08;4080 16GB&#xff09; 硬盘&#xff1a;60G 软件 python 版本推荐3.10 - 3.11 transformers 库版本推荐为 4.36.2 torch 推荐使用 2.0 及以上的版本&#xff0c;以获得最佳的推理性能 二、部…

重生奇迹mu恶魔来袭副本

在游戏重生奇迹mu中&#xff0c;恶魔来袭副本是玩家能够组队通过的副本。但是因为手游组队的不方便性&#xff0c;部分玩家对其还是非常苦手。而今天&#xff0c;我们就给大家讲解一下这个游戏的双人通关攻略。 1、挂机找怪手动输出 (1)对于普通剧情副本而言&#xff0c;挂机…

利用CNN-Bigru-Attention模型输电线路故障诊断(Python代码,TensorFlow框架,)

效果视频&#xff1a;利用CNN-Bigru-Attention模型输电线路故障诊断(Python代码&#xff0c;TensorFlow框架&#xff0c;压缩包带有数据集和代码&#xff0c;解压缩可直接运行)_哔哩哔哩_bilibili 售后包免费远程协助运行&#xff08;用向日葵或者todesk软件协助&#xff09; …

校园智能水电预付费管理系统

校园智能水电预付费管理系统是一种专为学校水电资源管理而设计的智能化系统&#xff0c;旨在提供全面的水电资源管理解决方案&#xff0c;满足校园管理者对水电资源管理的需求。该系统整合了先进的智能技术和云计算&#xff0c;为校园管理者提供了实时监控、自动计费、节能管理…

如何将图片你分辨率调整到350dpi?分辨率快速设置工具

图片的分辨率通常用在打印照片和一些考试平台对上传证件照的要求上&#xff0c;我们平时拍摄的图片dpi大多都是96的&#xff0c;所以不符合使用需求&#xff0c;那么怎么把这些比较低分辨率的图片修改到350dpi呢&#xff1f;试试本文分享的这几个方法吧&#xff0c;简单又方便。…

使用阿里云试用Elasticsearch学习:创建仪表板pivot、搜索discover和仪表板dashboard

文档&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/current/transform-examples.html#example-clientips 在kibana左栏打开Transforms&#xff0c;并创建Transforms&#xff08;转换&#xff09; Management > Stack Management > Data > T…

component-传入值圆形百分比展示,.background-image: conic-gradient()

1.效果 2.代码 <template><div class"circle" :style"{ background-image: conic-gradient(#3498db 0 ${fillPercentage}%, transparent ${fillPercentage}% 100%) }"></div> <!-- 使用动态绑定样式来设置填充效果 --> </temp…