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

news2025/4/17 3:27:27

目录

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

  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 structCSNode{
    ElemType data;
    structCSNode*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. 二叉树遍历算法的应用: 【数据结构】树与二叉树遍历算法的应用(求叶子节点个数、求树高、复制二叉树、创建二叉树、二叉树存放表达式、交换二叉树每个结点的左右孩子)

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

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

相关文章

回溯算法练习day.1

回溯算法 回溯法的作用 递归函数与回溯算法是相辅相成的,回溯法往往在递归函数的“下面” 使用原因:有些问题无法暴力进行搜索,只能通过回溯法来解决,例如 1.组合问题 2.切割问题 3.子集问题 4.排列问题 5.棋盘问题 回溯算法是一…

ubuntu 更改 ssh 默认端口 22 以加固安全

出于加固安全考虑,一般公司会禁用 ssh 的 22 端口号,因此我们需要改为其他端口。 1、ssh 命令行登录 进入台式机,修改 /etc/ssh/sshd_config 文件中的 Port 配置行,将 22 改为 8022,保存修改后,重启 ssh 服…

一起学习python——基础篇(19)

今天来说一下python的如何修改文件名称、获取文件大小、读取文中指定的某一行内容。 1、修改文件名称: import os testPath"D:/pythonFile/test.txt" testPath2"D:/pythonFile/test2.txt" #修改文件名称使用rename方法, #第一个参…

Java文件操作-IO流

一、文件 1.基本概念 文件:文件是保存数据的地方,比如经常使用的word文档,txt文件,excel文件…都是文件。它既可以保存一张图片,也可以保持视频,声音… 文件流:文件在程序中是以流的形式来操…

Java项目-源码!大学生兼职信息系统

大学生兼职信息系统 1、功能介绍1.1、演示视频 2、系统部分功能展示2.1、管理员登录2.2、管理员功能模块2.2.1、轮播图管理2.2.2、招聘信息管理2.2.3、企业信息管理 3、系统概述4、开发环境 1、功能介绍 本文以Java为开发技术,实现了一个大学生兼职信息系统。 功能…

SF506DS-ASEMI开关电源二极管SF506DS

编辑:ll SF506DS-ASEMI开关电源二极管SF506DS 型号:SF506DS 品牌:ASEMI 封装:TO-252 最大平均正向电流(IF):5A 最大循环峰值反向电压(VRRM):600V 最大…

.net框架和c#程序设计第三次测试

目录 一、测试要求 二、实现效果 三、实现代码 一、测试要求 二、实现效果 数据库中的内容&#xff1a; 使用数据库中的账号登录&#xff1a; 若不是数据库中的内容&#xff1a; 三、实现代码 login.aspx文件&#xff1a; <% Page Language"C#" AutoEventW…

MySQL Innodb中 可重复读隔离级别是否能完全规避幻读

一、MySQL 可重复读隔离级别下的幻读 在 MySQL Innodb引擎可重复读隔离级别下&#xff0c;已经尽可能最大程度的规避幻读的问题了&#xff0c;使得大多数情况下&#xff0c;重复读都是可以得到一致的结果。 针对于读数据&#xff0c;可以大致分为两种模式&#xff0c;快照读&…

【最新华为ensp模拟器安装(内含文件下载)】

详细安装步骤 ensp介绍ensp安装需要的软件具体安装步骤查看virtualbox 配置信息是否正确ensp配置相关测试ensp安装是否成功教程亲测没问题&#xff0c;需要的同学点个关注呗。。。。 ensp介绍 ensp是华为路由交换模拟器&#xff0c;目前e.huawei.com上已经下载不到&#xff0c…

二、Flask会话技术和模板语言

Cookie Session # views.py: 路由 + 视图函数 import datetimefrom flask import Blueprint, render_template, request, redirect, session from .models import *# 蓝图 blue = Blueprint(user, __name__)# 首页 可以写两个路由,都是访问同一个函数 @blue.route(/) @blue.ro…

关于机器学习/深度学习的一些事-答知乎问(二)

进化算法与深度强化学习算法结合如何进行改进&#xff1f; &#xff08;1&#xff09;进化算法普遍存在着样本效率低下的问题&#xff0c;虽然其探索度较高&#xff0c;但其本质为全局随机性搜索&#xff0c;需要在整个回合结束后才能更新其种群&#xff0c;而深度强化学习在每…

普乐蛙VR航天体验馆设备VR太空飞船VR元宇宙展厅

三天小长假就要来啦&#xff01;五一假期也即将到来。老板们想捉住人流量这个财富密码吗&#xff1f;那快快行动起来&#xff01;开启VR体验项目&#xff0c;假期赚翻天&#xff01;小编亲测&#xff01;&#xff01;这款设备刺激好玩&#xff0c;想必会吸引各位家长小孩、学生…

v-show和v-if的区别和使用场景(超级详细)

文章目录 一、v-show与v-if的共同点二、v-show与v-if的区别三、v-show与v-if原理分析# v-show原理v-if原理 四、v-show与v-if的使用场景参考文献 一、v-show与v-if的共同点 我们都知道在 vue 中 v-show 与 v-if 的作用效果是相同的(不含v-else)&#xff0c;都能控制元素在页面…

LangChain-25 ReAct 让大模型自己思考和决策下一步 AutoGPT实现途径、AGI重要里程碑

背景介绍 大模型ReAct&#xff08;Reasoning and Acting&#xff09;是一种新兴的技术框架&#xff0c;旨在通过逻辑推理和行动序列的构建&#xff0c;使大型语言模型&#xff08;LLM&#xff09;能够达成特定的目标。这一框架的核心思想是赋予机器模型类似人类的推理和行动能…

js基础知识+练习

一&#xff0c;JavaScript简单了解 1.什么是JavaScript JavaScript简称JS&#xff0c;是较为流行的一种前端编程语言&#xff0c;是一种脚本语言&#xff0c;通过解释器运行&#xff0c;主要在客户端&#xff08;浏览器&#xff09;上运行&#xff0c;现在也可以基于node.js在服…

程序员的故事:麦哲伦死于JAVA之争

程序员的故事&#xff1a;麦哲伦死于JAVA之争 1400年&#xff0c;永乐年间&#xff0c;永乐皇帝七点钟准时上班了&#xff0c;清了清嗓子&#xff0c;问道&#xff1a;大家都到了没有&#xff1f;今天我们开个会&#xff0c;主要是讲一下项目用什么语言&#xff1f; 元朝的时候…

airtest-ios真机搭建实践

首先阅读4 ios connection - Airtest Project Docs 在Windows环境下搭建Airtest对iOS真机进行自动化测试的过程相对复杂&#xff0c;因为iOS的自动化测试通常需要依赖Mac OS系统&#xff0c;但理论上借助一些工具和服务&#xff0c;Windows用户也可以间接完成部分工作。下面是…

Python中的回调函数和C中函数指针什么关系?

你好&#xff0c;我是安然无虞。 Python 回调 在Python中&#xff0c;‘回调函数’ (callback) 是指一个作为参数传递给其它代码的函数。 目的是在后者完成某些操作后调用这个传递进来的函数。 回调允许在执行异步操作或处理事件时通知调用者代码。 回调函数通常用于&#…

家庭网络防御系统搭建-虚拟机安装siem/securityonion网络连接问题汇总

由于我是在虚拟机中安装的security onion&#xff0c;在此过程中&#xff0c;遇到很多的网络访问不通的问题&#xff0c;通过该文章把网络连接问题做一下梳理。如果直接把securityonion 安装在物理机上&#xff0c;网络问题则会少很多。 NAT无法访问虚拟机 security onion虚拟…

团结引擎+OpenHarmony 1配置篇

团结引擎OpenHarmony 1 配置篇 app团结鸿蒙化第一课一 DevEco Studio 下载安装二 团结引擎三 出包 app团结鸿蒙化第一课 1 团结引擎配置2 DevEco Studio 配置 一 DevEco Studio 下载安装 申请开发者套件 1 注册华为账号 签署协议 官网 2 认真填写 DevEco Studio 开发套件申请…