【手写数据库内核组件】01 解析树的结构,不同类型的数据结构组多层的链表树,抽象类型统一引用格式

不同类型的链表

专栏内容

  • postgresql使用入门基础
  • 手写数据库toadb
  • 并发编程

个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

文章目录

  • 不同类型的链表
  • 概述
  • 1. 数据类型识别
    • 1.1 TLV格式介绍
    • 1.2 结构体分层定义
    • 1.3 定义抽象数据类型
  • 2. 链表定义
    • 2.1 数据节点定义
    • 2.2 链表类型定义
  • 节点解析
  • 链表遍历
  • 多级树链表
  • 总结
  • 结尾

概述


在实际使用中,会存在不同的数据类型,有基本类型,有自定义的结构体的复杂类型。

当这么丰富的数据出现时,只能记录到动态扩展的链表中,同时还能够查找,并按正确的类型取出。

本节就来介绍,在同一个链表中如何记录如此丰富的数据资源,分别从

  • 数据类型识别;
  • 链表的定义;
  • 节点解析;
  • 链表遍历
    四个方面来展开介绍。

1. 数据类型识别


要识别出不同的数据类型,这里介绍一种数据结构的定义格式TLV。

1.1 TLV格式介绍

TLV(tag-length-value)是一种用于以结构化方式表示数据的二进制格式。TLV在计算机网络协议、智能卡应用以及其他数据交换场景中经常被使用。TLV由以下三部分组成:

  1. 标签(Tag):唯一标识数据的类型。它通常是一个单字节或一小段字节序列, 可以是不同bit代表不同含义,也可以是整体表示序列。

  2. 长度(Length):数据字段的字节长度。在某些协议中,标签和长度字段的长度也会被包含在内。

  3. 值(Value):实际传输的数据,可以是任何类型或格式。

在这里插入图片描述

这种格式通过明确区分数据的类型、长度和具体内容,使得数据的解析和处理变得更加清晰和高效。

1.2 结构体分层定义

  • 首先定义复合类型,一般使用枚举类型进行定义。

在手写数据库toadb的src/sqlcore/node/nodeType.h文件中就有用到这种定义。

这里举例定义如下:

typedef enum NodeType
{T_START,/* parser nodes */T_List,T_MANAGER,T_HR,T_EMPLOYEE
}NodeType;
  • 然后在各复合类型的结构定中,前两个字段采用公共字段。

这里定义经理,HR,员工三个结构体类型,每个人都有一个sno员工号的数据,他们的个性化数据有:

  • 经理,有管理多少个员工;
  • HR,新入职了多少新员工;
  • 员工,对应的部门经理的工号;
typedef struct stManager
{NodeType type;int size;int sno;int employeeNum;
}stManager;typedef struct stHr
{NodeType type;int size;int sno;int newEmployeesNum;
}stHr;typedef struct stEmployee
{NodeType type;int size;int sno;int partMgr;
}stEmployee;

1.3 定义抽象数据类型

自定义的数据结构太多了,为了在使用中统一和简化,这里定义Node数据类型,是对上述数据类型的统称。

/* common type, real size is just by type. */
typedef struct Node
{NodeType type;int size;
}Node;

Node数据结构中包含两个公共的字段,类型和大小。

这样在参数引用,链表节点引用时,都可以用这个抽象的类型来代表以上众多的数据类型。

当然,有这个抽象结构定义之后,ListCell中的数据指针类型可以用Node类型代替,而不是之前定义的void。

2. 链表定义


既然是链表,肯定采用指针的方式串连起来,以往都是定义一种明确的数据类型作为链表的节点。

而面对如此多的数据类型,链表节点的结构如何定义呢?

2.1 数据节点定义

数据节点中存储真实的数据,由链表指针将数据节点串连起来。

它的定义如下:

/* tree list cell */
typedef struct ListCell
{void* pValue;struct ListCell *next;
}ListCell;
  • 数据类型不确定,所以定义为void *;
  • 单链表的形式,next指向下一个节点;

2.2 链表类型定义

部门的结构是一个多层级形式,每个层级又是多个员工,也是一个链表。

因此,数据类型中,除了实际意义的数据类型,如上面定义的经理,HR,员工外,还需要增加链表的数据类型。

/* tree list node */
typedef struct List
{NodeType type;int size;int length;         /* number of ListCell struct */ListCell *head;
}List;

链表的数据类型中,数据有两个:

  • length, 链表中的节点个数;
  • head,链表头;

节点解析


数据的多样性,增加了链表节点类型解析工作,因为之前采用了统一类型定义,所以类型的解析变得简单。

采用统一的接口对类型进行解析, 分发到对应的类型进行处理。

static void ShowNode(Node *n)
{if(NULL == n){return;}switch(n->type){case T_List:ShowNodList(n);break;case T_MANAGER:ShowNodManager(n);break;case T_HR:ShowNodHR(n);break;case T_EMPLOYEE:ShowNodEmployee(n);break;default:break;}
}

这里定义了一个展示各节点信息的接口,根据节点类型再调用各自的接口进行展示。

链表遍历


经过上面的抽象类型之后,链表的遍历就非常简单,这里以链表的节点的显示为例。

void TravelListCell(List *list)
{ListCell *tmpCell = NULL;List *l = list;if(NULL == l){return;}/* list cell node show */for(tmpCell = l->head; tmpCell != NULL; tmpCell = tmpCell->next){Node *node = (Node *)(tmpCell->pValue);ShowNode(node);}return;
}

说明:

  • 传入的是一个List的指针,这里会包含一个链表;
  • 从成员head开始遍历,直到链表节点的next为空,也就是链尾;
  • 将链表节点的数据成员转为抽象类型Node *, 传入统一的处理接口;

多级树链表


将经理的数据成员增加一项,除了下属成员数量外,还列出下属的员工信息;

typedef struct stManager
{NodeType type;int size;int sno;int employeeNum;Node *employeeList;
}stManager;

这里有个特别的地方,对于T_List类型的数据,内部会递归调用TravelListCell,这样就是一个多级链表树。

在这里插入图片描述

如同一个公司的组织架构一样,顶层由HR,高级经理列表组成,每个高级经理下属由员工,中级经理组成;

而中级经理下属由多名员工组成,整体组成一个公司的树形组织架构图。

对于T_LIst类型的节点,它的显示处理函数如下:

void ShowNodList(Node *n)
{if(NULL == n)return ;TravelListCell((List *) n);
}

其实是深度优先的图递归遍历,其它数据节点的显示就相对简单,打印成员信息即可,这里不再列举。

总结


本文介绍了链表节点为不同数据类型时的处理方法,定义了抽象类型后使引用的类型统一,同时在遍历树形链表时,对于成员仍为链表时,采用深度优先的递归遍历。

这种链表在数据库内核中应用比较广泛,比如在SQL语法解析时,将语法的各子句解析成不同的数据类型,而像select子句,可以写多个列名,该子句内部又以链表形成存储列信息。

结尾


非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

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

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

相关文章

Go语言--复合类型之map、结构体

map Go 语言中的 map(映射、字典)是一种内置的数据结构,它是一个无序的 key-value 对的集合,比如以身份证号作为唯一键来标识一个人的信息。 格式 map [keyType]valueType 在一个 map 里所有的键都是唯一的,而且必须是支持和!操作符的类型…

pytorch、pytorch_lightning、torchmetrics版本对应

目录 1.pytorch_lightning对应版本安装 2.PyTorch Lightning介绍 PyTorch Lightning 的作用: PyTorch Lightning 的基本用法: 报错:ModuleNotFoundError: No module named pytorch_lightning 这种报错一看就是缺了pytorch_lightning包&am…

Linux防火墙使用(firewalld与iptables)

防火墙概述 防火墙是一种由硬件和软件组合而成,在内部网和外部网之间、专有网和公共网之间构造的保护屏障,用以保护用户资料和信息安全的一种技术 防火墙作用在于及时发现并处理计算机网络运行时可能存在的安全风险、数据传输等问题,从而实现…

VUE3初学入门-02-VUE创建项目

创建VUE项目的另一个方法 三种方法通过vue-cli进行创建通过npm进行创建比较 部署到nginx修改配置生成部署文件 三种方法 上一篇是在VSCODE中建立工作区,然后创建,属于命令加鼠标方式。个人感觉,在VSCODE基本上都是这样的操作,不是…

Superset超火的企业级可视化BI分析工具

Superset,听起来就像是超级集合,确实,它几乎集合了所有你需要的数据功能。简单说,它就是一个现代化、功能强大的数据可视化工具。 它支持各种数据库,有着丰富的可视化选项,可以用来创建漂亮的数据仪表盘&a…

Python面试宝典第6题:有效的括号

题目 给定一个只包括 (、)、{、}、[、] 这些字符的字符串,判断该字符串是否有效。有效字符串需要满足以下的条件。 1、左括号必须用相同类型的右括号闭合。 2、左括号必须以正确的顺序闭合。 3、每个右括号都有一个对应的相同类型的左括号。 注意:空字符…

Xilinx FPGA:vivado串口输入输出控制fifo中的数据

一、实验要求 实现同步FIFO回环测试,通过串口产生数据,写入到FIFO内部,当检测到按键信号到来,将FIFO里面的数据依次读出。 二、信号流向图 三、状态转换图 四、程序设计 (1)按键消抖模块 timescale 1ns…

读书笔记-《魔鬼经济学》

这是一本非常有意思的经济学启蒙书,作者探讨了许多问题,并通过数据找到答案。 我们先来看看作者眼中的“魔鬼经济学”是什么,再选一个贴近我们生活的例子进行阐述。 01 魔鬼经济学 中心思想:假如道德代表人类对世界运转方式的期…

uniapp实现一个键盘功能

前言 因为公司需要&#xff0c;所以我.... 演示 代码 键盘组件代码 <template><view class"keyboard_container"><view class"li" v-for"(item, index) in arr" :key"index" click"changArr(item)" :sty…

初学Spring之 AOP 面向切面编程

AOP&#xff08;Aspect Oriented Programming&#xff09;面向切面编程 通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术 是面向对象&#xff08;OOP&#xff09;的延续 AOP 在 Spring 中的作用&#xff1a; 1.提供声明式事务 2.允许用户自定义切面 导…

Objects365数据集介绍

Objects365数据集介绍 什么是Objects365数据集&#xff1f;数据集的规模与内容数据集的特点数据集下载 什么是Objects365数据集&#xff1f; Objects365是一个大规模、高质量的物体检测数据集。该数据集旨在推动物体检测技术的发展&#xff0c;特别是在真实世界场景下的应用。O…

【python】python当当数据分析可视化聚类支持向量机预测(源码+数据集+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

基于java+springboot+vue实现的校园外卖服务系统(文末源码+Lw)292

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;外卖信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

使用Charles mock服务端响应数据

背景 服务端未提供接口/服务端接口返回结果有逻辑限制&#xff08;次数限制&#xff09;&#xff0c;不能通过原始接口返回多次模拟预期的返回结果&#xff0c;例如边界值情况 客户端受到接口响应数据的限制&#xff0c;无法继续开发或测试&#xff0c;会极大影响开发测试效率…

QT滑块图片验证程序

使用QT实现滑块验证程序&#xff0c;原理是画个图片&#xff0c;然后在图片上画个空白区域&#xff0c;再画个滑块图片。 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widg…

文心智能体平台快速创建一个HY(Lisp)编程小助手

现在可以在文心智能体平台&#xff0c;使用文心一言创建各种智能体了&#xff01;创建步骤如下&#xff1a; 创建知识库 可以使用本地上传的方式来提交&#xff0c;鼠标移动到”查看模板“&#xff0c;可以下载”知识库外链上传示例模版.xlsx“&#xff0c;按照模板里的格式&…

8.14 矢量图层面要素2.5D渲染

文章目录 前言2.5D渲染QGis设置面符号为2.5D二次开发代码实现2.5D 总结 前言 本章介绍矢量图层面要素2.5D渲染的使用说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 2.5D渲染 2.5D渲染可以将多边形渲染为类3D效果。 QGis设置面符号为2.5D 以"hou…

生成式AI的短板在于“Token”的存在

生成式AI模型处理文本的方式与人类不同。理解它们基于“token”的内部环境&#xff0c;可能有助于解释一些奇怪行为和固有局限性。 从小型设备上的Gemma到OpenAI领先行业的GPT-4o&#xff0c;大多数模型都是基于一种称为Transformer的架构。由于Transformer在将文本与其他类型…

[Multi-Modal] MDETR 论文及代码学习笔记

代码地址&#xff1a;https://github.com/ashkamath/mdetr 论文地址&#xff1a;https://arxiv.org/abs/2104.12763 多模态推理系统依靠预先训练的目标检测器从图像中提取感兴趣区域&#xff08;边界框包围区域&#xff09;。然而&#xff0c;这个关键模块通常被用作黑匣子&…

飞书 API 2-4:如何使用 API 将数据写入数据表

一、引入 上一篇创建好数据表之后&#xff0c;接下来就是写入数据和对数据的处理。 本文主要探讨数据的插入、更新和删除操作。所有的操作都是基于上一篇&#xff08;飞书 API 2-4&#xff09;创建的数据表进行操作。上面最终的数据表只有 2 个字段&#xff1a;序号和邮箱。序…