【数据结构】树与二叉树(十八):树的存储结构——Father链接结构、儿子链表链接结构

文章目录

  • 5.1 树的基本概念
    • 5.1.1 树的定义
    • 5.1.2 森林的定义
    • 5.1.3 树的术语
  • 5.2 二叉树
  • 5.3 树
    • 5.3.1 树的存储结构
      • 1. 理论基础
      • 2. 典型实例
    • 5.3.2 Father链接结构
      • a. 定义树节点结构
      • b. 创建新节点
      • c. 主函数
      • d. 代码整合
    • 5.3.3 儿子链表链接结构
      • a. 定义树节点结构
      • b. 创建新节点
      • c. 添加子节点作为第一个子节点
      • d. 遍历树打印节点数据
      • e. 主函数
      • f. 代码整合

5.1 树的基本概念

5.1.1 树的定义

  • 一棵树是结点的有限集合T:
    • 若T非空,则:
      • 有一个特别标出的结点,称作该树的,记为root(T);
      • 其余结点分成若干个不相交的非空集合T1, T2, …, Tm (m>0),其中T1, T2, …, Tm又都是树,称作root(T)的子树
    • T 空时为空树,记作root(T)=NULL。

5.1.2 森林的定义

  一个森林是0棵或多棵不相交(非空)树的集合,通常是一个有序的集合。换句话说,森林由多个树组成,这些树之间没有交集,且可以按照一定的次序排列。在森林中,每棵树都是独立的,具有根节点和子树,树与树之间没有直接的连接关系。
  森林是树的扩展概念,它是由多个树组成的集合。在计算机科学中,森林也被广泛应用于数据结构和算法设计中,特别是在图论和网络分析等领域。
在这里插入图片描述

5.1.3 树的术语

  • 父亲(parent)、儿子(child)、兄弟(sibling)、后裔(descendant)、祖先(ancestor)
  • 度(degree)、叶子节点(leaf node)、分支节点(internal node)
  • 结点的层数
  • 路径、路径长度、结点的深度、树的深度

参照前文:【数据结构】树与二叉树(一):树(森林)的基本概念:父亲、儿子、兄弟、后裔、祖先、度、叶子结点、分支结点、结点的层数、路径、路径长度、结点的深度、树的深度

5.2 二叉树

5.3 树

5.3.1 树的存储结构

1. 理论基础

  1. Father链接结构:

    • 在这种结构中,每个节点除了存储数据外,还包含一个指向其父节点的指针。
    • 这种结构使得查找父节点很容易,但对于查找子节点则较为困难,因为需要遍历整个树。
    • 在二叉树中,每个节点最多有一个父节点,但在一般的树中,节点可以有多个父节点。
  2. 儿子链表链接结构:

    • 在这种结构中,每个节点包含一个指向其第一个子节点的指针,以及一个指向其下一个兄弟节点的指针。
    • 这种结构使得查找子节点很容易,但查找父节点较为困难,可能需要遍历兄弟节点链表直到找到相应的父节点。
  3. 左儿子右兄弟链接结构:

    • 也称为孩子兄弟表示法,每个节点包含一个指向其第一个子节点的指针,以及一个指向其下一个兄弟节点的指针。
    • 在这种结构中,树的每一层被表示为一个单链表,子节点通过左链连接,兄弟节点通过右链连接。
    • 这种结构既方便查找父节点,又方便查找子节点和兄弟节点,被广泛用于一般的树的表示。

  选择合适的树的存储结构通常取决于具体应用的需求。 Father链接结构适合于查找父节点的操作频繁,而儿子链表链接结构和左儿子右兄弟链接结构适用于频繁查找子节点的情况。

2. 典型实例

在这里插入图片描述

  1. Father链接结构:
    • A节点:父指针为null(A为根节点)
    • B节点:父指针指向A
    • C节点:父指针指向A
    • D节点:父指针指向A
    • E节点:父指针指向C
    • F节点:父指针指向C
  2. 儿子链表链接结构:
    • A节点:子节点链表为B、C、D
    • B节点:子节点链表为null
    • C节点:子节点链表为E、F
    • D节点:子节点链表为null
    • E节点:子节点链表为null
    • F节点:子节点链表为null
  3. 左儿子右兄弟链接结构:
    • A节点:左儿子为B,右兄弟为null
    • B节点:左儿子为null,右兄弟为C
    • C节点:左儿子为E,右兄弟为D
    • D节点:左儿子为null,右兄弟为null
    • E节点:左儿子为null,右兄弟为F
    • F节点:左儿子为null,右兄弟为null

5.3.2 Father链接结构

a. 定义树节点结构

typedef struct TreeNode {char data;              // 节点数据struct TreeNode* parent; // 指向父节点的指针
} TreeNode;

b. 创建新节点

TreeNode* createNode(char data) {TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));if (newNode == NULL) {fprintf(stderr, "Memory allocation failed\n");exit(EXIT_FAILURE);}newNode->data = data;newNode->parent = NULL;return newNode;
}

c. 主函数

int main() {// 创建节点TreeNode* nodeA = createNode('A');TreeNode* nodeB = createNode('B');TreeNode* nodeC = createNode('C');TreeNode* nodeD = createNode('D');TreeNode* nodeE = createNode('E');TreeNode* nodeF = createNode('F');// 构建树结构,设置父指针nodeB->parent = nodeA;nodeC->parent = nodeA;nodeD->parent = nodeA;nodeE->parent = nodeC;nodeF->parent = nodeC;// 打印每个节点及其父节点printf("Node %c, Parent: %c\n", nodeA->data, (nodeA->parent ? nodeA->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeB->data, (nodeB->parent ? nodeB->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeC->data, (nodeC->parent ? nodeC->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeD->data, (nodeD->parent ? nodeD->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeE->data, (nodeE->parent ? nodeE->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeF->data, (nodeF->parent ? nodeF->parent->data : 'N'));// 释放内存free(nodeA);free(nodeB);free(nodeC);free(nodeD);free(nodeE);free(nodeF);return 0;
}

d. 代码整合

#include <stdio.h>
#include <stdlib.h>// 定义树节点结构
typedef struct TreeNode {char data;              // 节点数据struct TreeNode* parent; // 指向父节点的指针
} TreeNode;// 创建新节点的函数
TreeNode* createNode(char data) {TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));if (newNode == NULL) {fprintf(stderr, "Memory allocation failed\n");exit(EXIT_FAILURE);}newNode->data = data;newNode->parent = NULL;return newNode;
}int main() {// 创建节点TreeNode* nodeA = createNode('A');TreeNode* nodeB = createNode('B');TreeNode* nodeC = createNode('C');TreeNode* nodeD = createNode('D');TreeNode* nodeE = createNode('E');TreeNode* nodeF = createNode('F');// 构建树结构,设置父指针nodeB->parent = nodeA;nodeC->parent = nodeA;nodeD->parent = nodeA;nodeE->parent = nodeC;nodeF->parent = nodeC;// 打印每个节点及其父节点printf("Node %c, Parent: %c\n", nodeA->data, (nodeA->parent ? nodeA->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeB->data, (nodeB->parent ? nodeB->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeC->data, (nodeC->parent ? nodeC->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeD->data, (nodeD->parent ? nodeD->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeE->data, (nodeE->parent ? nodeE->parent->data : 'N'));printf("Node %c, Parent: %c\n", nodeF->data, (nodeF->parent ? nodeF->parent->data : 'N'));// 释放内存free(nodeA);free(nodeB);free(nodeC);free(nodeD);free(nodeE);free(nodeF);return 0;
}

在这里插入图片描述

注:其他操作……有缘再见

5.3.3 儿子链表链接结构

a. 定义树节点结构

struct TreeNode {char data;struct TreeNode* child;struct TreeNode* sibling;
};

b. 创建新节点

struct TreeNode* createNode(char data) {struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));newNode->data = data;newNode->child = NULL;newNode->sibling = NULL;return newNode;
}

c. 添加子节点作为第一个子节点

void addChild(struct TreeNode* parent, struct TreeNode* child) {child->sibling = parent->child;parent->child = child;
}

d. 遍历树打印节点数据


void traverseTree(struct TreeNode* root) {if (root != NULL) {printf("%c\n", root->data);struct TreeNode* child = root->child;while (child != NULL) {printf("  %c (Child)\n", child->data);child = child->sibling;}// 递归遍历每个子节点child = root->child;while (child != NULL) {traverseTree(child);child = child->sibling;}}
}

e. 主函数

int main() {// 创建树节点struct TreeNode* A = createNode('A');struct TreeNode* B = createNode('B');struct TreeNode* C = createNode('C');struct TreeNode* D = createNode('D');struct TreeNode* E = createNode('E');struct TreeNode* F = createNode('F');// 构建树结构addChild(A, B);addChild(A, C);addChild(A, D);addChild(C, E);addChild(C, F);// 遍历并打印树节点traverseTree(A);// 释放内存free(A);free(B);free(C);free(D);free(E);free(F);return 0;
}

在这里插入图片描述

f. 代码整合

#include <stdio.h>
#include <stdlib.h>// 定义树节点结构
struct TreeNode {char data;struct TreeNode* child;struct TreeNode* sibling;
};// 创建新节点
struct TreeNode* createNode(char data) {struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));newNode->data = data;newNode->child = NULL;newNode->sibling = NULL;return newNode;
}// 添加子节点作为第一个子节点
void addChild(struct TreeNode* parent, struct TreeNode* child) {child->sibling = parent->child;parent->child = child;
}// 遍历树并打印节点
void traverseTree(struct TreeNode* root) {if (root != NULL) {printf("%c\n", root->data);struct TreeNode* child = root->child;while (child != NULL) {printf("  %c (Child)\n", child->data);child = child->sibling;}// 递归遍历每个子节点child = root->child;while (child != NULL) {traverseTree(child);child = child->sibling;}}
}int main() {// 创建树节点struct TreeNode* A = createNode('A');struct TreeNode* B = createNode('B');struct TreeNode* C = createNode('C');struct TreeNode* D = createNode('D');struct TreeNode* E = createNode('E');struct TreeNode* F = createNode('F');// 构建树结构addChild(A, B);addChild(A, C);addChild(A, D);addChild(C, E);addChild(C, F);// 遍历并打印树节点traverseTree(A);// 释放内存free(A);free(B);free(C);free(D);free(E);free(F);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【IDEA 使用easyAPI、easyYapi、Apifox helper等插件时,导出接口文档缺少代码字段注释的相关内容、校验规则的解决方法】

问题 IDEA 使用easyAPI、easyYapi、Apifox helper等插件时&#xff0c;导出的接口文档上面&#xff0c;缺少我们代码里的注解字段&#xff0c;如我们规定了NOTNULL、字段描述等。 问题链接&#xff0c;几个月之前碰到过&#xff0c;并提问了&#xff0c;到现在解决&#xff0c…

Docker之DockerFile解析

DockerFile解析 是什么 Dockerfile是用来构建Docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。 概述 官网 https://docs.docker.com/engine/reference/builder/ 构建三步骤 编写Dockerfile文件 docker build命令构建镜像 docker run依镜像运…

元宇宙3D云展厅应用到汽车销售的方案及特点

为了紧紧抓住年轻消费者的需求&#xff0c;汽车销售行业也正在经历一场深刻的变革。在这个变革的前沿&#xff0c;元宇宙3D汽车展厅作为一项全新技术闪亮登场&#xff0c;打破了传统汽车销售模式的限制&#xff0c;为消费者带来了前所未有的购车体验。 元宇宙3D汽车展厅采用了尖…

进程概述

文章目录 计算机算机组成因特尔CPU型号摩尔定律衡量CPU的指标指令&#xff08;Instruction)操作系统&#xff08;Operating System&#xff09;虚拟地址空间&#xff08;Virtual Address Space&#xff09;进程(Process/task)进程管理(PCB - 进程控制块)进程控制块&#xff08;…

基于SSM的古董拍卖系统

基于SSM的古董拍卖系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringMyBatisSpringMVC工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 拍卖界面 管理员界面 摘要 古董拍卖系统是一个基于SSM框架&#xff08;Spring …

JRC Monthly Water History, v1.4数据集

简介&#xff1a; JRC Monthly Water History产品&#xff0c;是利用1984至2020年获取的landsat5、landsat7和landsat8的卫星影像&#xff0c;生成的一套30米分辨率的全球地表水覆盖的月度地表水监测地图集。该数据集共有442景数据&#xff0c;包含1984年3月至2020年12月间的月…

Kubernetes Dashboard部署ImagePullBackOff问题处理

通常&#xff0c;出现ImagePullBackOff问题是由于Kubernetes集群无法拉取所需的镜像导致的。解决这个问题的方法通常包括以下步骤&#xff1a; 1. 检查Pod的描述信息&#xff1a; kubectl describe pod/[pod名称] --namespacekubernetes-dashboard 查看Events部分是否有关于…

项目踩坑之面试遇到的问题及解决

第一点&#xff1a; 问题 遇到的问题之&#xff1a;在实现后台管理端-账户操作的时候&#xff0c;添加员工的时候如果重复添加同一个员工&#xff0c;会触发一个数据库唯一约束异常&#xff0c;但客户端无法清晰的理解这个错误&#xff0c;所以我们就对新增员工的代码进行try…

4.1 Windows驱动开发:内核中进程与句柄互转

在内核开发中&#xff0c;经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符&#xff08;PID&#xff09;来标识&#xff0c;而句柄是指对内核对象的引用。在Windows内核中&#xff0c;EProcess结构表示一个进程&#xff0c;而HANDLE是一个句柄。 为了实…

kubernetes 高可用集群

目录 一、haproxy负载均衡 二、pacemaker高可用 三、部署control-plane 四、部署worker node 实验环境 主机名 IP 角色 docker 192.168.67.10 harbor k8s1 192.168.67.11 control-plane k8s2 192.168.67.12 control-plane k8s3 192.168.67.13 control-plane k8s…

vscode文件夹折叠问题

今天发现一个vscode的文件夹显示的问题&#xff0c;首先是这样的&#xff0c;就是我的文件夹里又一个子文件夹&#xff0c;子文件夹里有一些文件&#xff0c;但是我发现无法折叠起这个子文件夹&#xff0c;总是显示全部的文件&#xff0c;这让我备份很难&#xff0c;具体参考 h…

邀请报名|11月24日阿里云原生 Serverless 技术实践营 深圳站

活动简介 “阿里云云原生 Serverless 技术实践营 ” 是一场以 Serverless 为主题的开发者活动&#xff0c;活动受众以关注 Serverless 技术的开发者、企业决策人、云原生领域创业者为主&#xff0c;活动形式为演讲、动手实操&#xff0c;让开发者通过一个下午的时间增进对 Ser…

Vue3-watchEffect函数

Vue3-watchEffect函数 功能&#xff1a;watchEffect 函数在一开始时就会执行一次&#xff0c;而当中的回调函数的属性发生变化&#xff0c;那么watchEffect 就会再执行一次&#xff0c;主要作用还是在于监视回调函数每次的变化。 // App.vue <template><h2>计数…

【C++】【Opencv】cv::warpAffine()仿射变换函数详解,实现平移、缩放和旋转等功能

仿射变换是一种二维变换&#xff0c;它可以将一个二维图形映射到另一个二维图形上&#xff0c;保持了图形的“形状”和“大小”不变&#xff0c;但可能会改变图形的方向和位置。仿射变换可以用一个线性变换矩阵来表示&#xff0c;该矩阵包含了六个参数&#xff0c;可以进行平移…

获取虎牙直播源

为了今天得LOL总决赛 然后想着下午看看 但是网页看占用高 就想起来有个直播源 也不复杂看了大概一个小时 没啥问题 进入虎牙页面只有 直接F12 网络 然后 看这个长条 一直在获取 发送 那就选中这个区间 找到都是数字这一条 如果直接访问的话会一直下载 我这都取消了 然后 打开…

常见面试题-MySQL的Explain执行计划

了解 Explain 执行计划吗&#xff1f; 答&#xff1a; explain 语句可以帮助我们查看查询语句的具体执行计划。 explain 查出来的各列含义如下&#xff1a; id&#xff1a;在一个大的查询语句中&#xff0c;每个 select 关键字都对应一个唯一的 id select_type&#xff1a;…

八股文-面向对象的理解

近年来&#xff0c;IT行业的环境相较以往显得有些严峻&#xff0c;因此一直以来&#xff0c;我都怀有一个愿望&#xff0c;希望能够创建一个分享面试经验的网站。由于个人有些懒惰&#xff0c;也较为喜欢玩乐&#xff0c;导致计划迟迟未能实现。然而&#xff0c;随着年底的临近…

windows安装wsl2以及ubuntu

查看自己系统的版本 必须运行 Windows 10 版本 2004 及更高版本&#xff08;内部版本 19041 及更高版本&#xff09;或 Windows 11 才能使用以下命令 在设置&#xff0c;系统里面就能看到 开启windows功能 直接winQ搜 开启hyber-V、使用于Linux的Windows子系统、虚拟机平…

让文字在盒子中水平居中与垂直居中

简单方法&#xff1a; 1.先用text-align: center;将文字垂直居中。 2.再用line-height: Xpx;将元素的行高设置为与父元素同样的高度。&#xff08;这里的X代表父元素的高度&#xff09; 举例&#xff1a; 对于该网页的代码如下&#xff1a; <!DOCTYPE html> <html&…

wpf devexpress绑定grid到总计和分组统计

此主题描述了如何在gridcontrol中的视图模型和显示定义总计和分组统计 在视图模型中指定统计 1、创建 SummaryItemType 枚举你想要在GridControl中显示的统计类型&#xff1a; public enum SummaryItemType { Max, Count, None } 2、创建一个grid统计描述类 public class S…