当前位置: 首页 > news >正文

数据结构-数组(稀疏矩阵转置)和广义表

目录

  • 1、数组
      • 定义
    • 1)数组存储地址计算
      • 示例
        • ①行优先
        • ②列优先
    • 2)稀疏矩阵的转置
      • 三元组顺序表
        • 结构定义
      • ①普通矩阵转置
      • ②三元组顺序表转置稀疏矩阵
      • ③稀疏矩阵的快速转置
    • 3)十字链表
      • 结构定义
  • 2、广义表
      • 定义
    • 1)基本操作
      • ①GetHead
      • ②GetTail
    • 2)构造存储结构的两种方法
      • 表头表尾
        • 结构定义
    • 3)递归算法
      • ①求广义表深度
      • ②复制广义表
      • ③创建广义表

1、数组

定义

数组是一种用于存储多个相同类型数据的集合,其元素在内存中连续存放并按照一定的顺序排列。这种有序性和连续性使得数组在访问时具有较高的效率。数组的特点包括所有元素具有相同的数据类型、可以通过索引快速访问任意元素、支持各种操作如遍历和排序等,并且数组的定义和初始化方式在不同编程语言中有所不同。

1)数组存储地址计算

数组存储地址的计算主要依赖于数组的起始地址、元素的数据类型(即每个元素所占的字节数)以及元素的下标位置

一维数组的存储地址计算

首元素地址:假设一维数组A的首地址为L,且每个元素占用C个字节。则数组中任意元素A[i]的地址可以通过公式Loc(A[i]) = L + i * C来计算。
示例:如果数组A的首地址是1000,每个元素占4个字节,那么A[3]的地址就是1000 + 3 * 4 = 1012。

二维数组的存储地址计算

行优先存储:在行优先存储中,二维数组的元素按照行的顺序依次存储。对于二维数组B[m][n],元素B[i][j]的地址计算公式为Loc(B[i][j]) = Loc(B[0][0]) + (i * n + j) * C,其中C是每个元素占用的字节数。
列优先存储:在列优先存储中,二维数组的元素按照列的顺序依次存储。对于二维数组B[m][n],元素B[i][j]的地址计算公式为Loc(B[i][j]) = Loc(B[0][0]) + (j * m + i) * C。
示例:假设有一个3x4的二维数组B,按行优先存储,首地址为1000,每个元素占2个字节。那么B[2][3]的地址就是1000 + (2*4 + 3) * 2 = 1026。

多维数组的存储地址计算

对于更高维度的数组,地址计算方法类似,只是需要考虑更多维度的索引和步长。
例如,按行优先存储的三维数组D[m][n][p]的元素D[i][j][k]的地址计算公式为Loc(D[i][j][k]) = Loc(D[0][0][0]) + ((i * n * p + j * p + k) * C)。
列优先:Loc(D[i][j][k]) = Loc(D[0][0][0]) + (knm+j*m+i)*C

示例

数组A[9][3][5][8],首地址为100,每个元素占4个字节,求a[8][2][4][7]的地址

①行优先

100+(8358+258+48+7)*4

②列优先

100+(7539+439+29+8)*4

2)稀疏矩阵的转置

三元组顺序表

由于稀疏矩阵中含有大量的零元素,空间利用率很低,所以需要三元组顺序表来表示稀疏矩阵中的非零元素,它通过行优先的顺序将非零元素及其位置信息存储在一个线性表中,节省存储空间并简化运算

在这里插入图片描述
在这里插入图片描述

结构定义
typedef struct{int i,j;//该非零元的行下标和列下标ElemType e;
}Triple;
typedef struct{Triple data[MAXSIZE + 1];//非零元三元组表,data[0]未用int mu,nu,tu;//矩阵的行数、列数和非零元总数
TSMatrix;

①普通矩阵转置

for(col = 1;col <= nu;++col)for(row = 1;row <= mu;++row)T[col][row] = M[row][col];

②三元组顺序表转置稀疏矩阵

Status TransposeSMatrix(TSMatrix M, TSMatrix &T){//采用三元组表存储表示,求稀疏矩阵M的转置矩阵TT.mu = M.nu;  T.nu = M.mu;  T.tu = M.tu;if(T.tu){q = 1;for(col = 1; col <= M.nu; ++col)for(p = 1; p <= M.tu; ++p)if(M.data[p].j == col){T.data[q].i = M.data[p].j;  T.data[q].j = M.data[p].i;T.data[q].e = M.data[p].e;  ++q;}}return OK;
}//TransposeSMatrix

③稀疏矩阵的快速转置

如果能预先确定就诊M中每一列(即T中的每一行)的第一个非零元在b.data中应有的位置,那么在对a.data中的三元组一次作转置时,便可直接放到b.data中恰当的位置上去,提高运算效率。

为此,需要附设num和cpot两个向量。num[col]表示矩阵M中第col列中非零元的个数,cpot[col]指示M中第col列的第一个非零元在b.data中的恰当位置。显然有
cpot[1] = 1;
cpot[col] = cpot[col - 1] + num[col - 1], 2 <= col <= a.nu
在这里插入图片描述

接下来就可以利用num和cpot向量快速确定转置后各元素在三元组表中的位置,提高运行效率

Status FastTransposeSMatrix(TSMatrix M, TSMatrix &T){//采用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵TT.mu = M.nu;  T.nu = M.mu;  T.tu = M.tu;if(T.tu){for(col = 1; col <= M.nu; ++col)num[col] = 0;for(t = 1; t <= M.tu; ++t)++num[M.data[t].j];//求M中每一列含非零元个数cpot[1] = 1;//求第col列中第一个非零元在b.data中的序号for(col = 2; col <= M.nu; ++col)cpot[col] = cpot[col - 1] + num[col - 1];for(p = 1; p <= M.tu; ++p){col = M.data[p].j;  q = cpot[col];T.data[q].i = M.data[p].j;  T.data[q].j = M.data[p].i;T.data[q].e = M.data[p].e;  ++cpot[col];//当一列的第一个元素转置完成后,下一个需要转置的是三元组表的下一个位置}//for}//ifreturn OK;
//FastTransposeSMatrix

3)十字链表

十字链表是一种用于表示稀疏矩阵的特殊存储结构,它通过行优先的顺序将非零元素及其位置信息存储在一个线性表中。每个节点包含五个字段:行号、列号、值、向下指针和向右指针,从而形成一个十字交叉的链表结构。这种结构不仅节省了存储空间,还提高了运算效率,并使得对稀疏矩阵的操作更加灵活和高效。

在这里插入图片描述

结构定义

typedef struct OLNode{int i,j;//该非零元的行和列下标ElemType e;struct OLNode *right,*down;//该非零元所在行表和列表的后继链域
}OLNode; *OLink;typedef struct{OLink *rhead,*chead;int mu,nu,tu;//稀疏矩阵的行数、列数、非零元总数
}CrossList;

2、广义表

定义

广义表是一种非线性的数据结构,它允许表中的元素既可以是单个数据项(原子),也可以是另一个广义表。这种结构使得广义表能够表示复杂的嵌套关系和层次结构。广义表的特点包括其元素的多样性(可以是原子或其他广义表)、结构的灵活性(可以嵌套任意深度)以及操作的复杂性(如求表头、表尾等)。在存储上,广义表通常采用链式结构来表示,以方便处理其复杂的嵌套关系。

1)基本操作

①GetHead

获取广义表的第一个元素,可以是原子,可以是列表

②GetTail

除了广义表中第一个元素的所有其他元素的集合,无论该元素是什么,都需要在外面额外套上一个(),即使是空表,或该值本来就有()

该部分主要是在给出一个广义表时能正确获取表头和表尾

2)构造存储结构的两种方法

表头表尾

结构定义
typedef struct GLNode{ElemTag tag;//公共部分,用于区分原子结点和表结点union{//原子结点和表结点的联合部分AtomType atom;//atom是原子结点的值域,AtomType由用户定义struct{struct GLNode *hp,*tp;}ptr;//ptr是表结点的指针域,ptr.hp和[tr.tp分别指向表头和表尾};
}*GList;//广义表类型

示例:
A = ()
B = (e)
C = (a,(b,c,d))
D = (A,B,C)
E = (a,E)//递归表 E = (a,(a,(a,…)))
在这里插入图片描述

另一种方法我还没理解,就不在这里说了

3)递归算法

由于广义表的定义本身就具有一定的递归性,且其子表问题与其本身的问题具有极高相似度、关联性,所有递归算法与广义表操作具有极好的适配性

①求广义表深度

int GListDepth(GList L){//采用头尾链表存储结构,求广义表L的深度。if C!L) return 1// 空表深度1if (L—> tag == ATOM) return 0;// 原子深度 0for (max=0, pp=L; PP; pp=pp->ptr. tp) {dep = GListDepth(pp—>Ptr.hp);// 求以 pp—>ptr.hp 为头指针的子表深度if (dep > max) max = dep;}return max + 1//非空表的深度是各元素的深度的最大值+1
}// GListDepth

②复制广义表

Status CopyGList(GList &T, GList L) {// 采用头尾链表存储结构,由广义表L复制得到广义表T。if(!L)  T = NULL;// 复制空表else {if(!(T= (GList) malloc(sizeof(GL.Node))))exit(OVERFLOW);// 建表结点T -> tag = L -> tag;if (L—> tag == ATOM) T -> atom = L -> atom;// 复制单原子else {CopyGList(T-> ptr. hp, L->ptr. hp) ;// 复制广义表L->ptr.hp 的一个副本T->ptr.hpCopyGList(T—> ptr. tp, L->ptr. tp);// 复制广义表L->ptr.tp 的一个副本T->ptr.tp} // else} // elsereturn OK;
}// CopyGList

③创建广义表

三种情况:

  1. 带括弧的空白串
  2. 长度为1的单字符串
  3. 长度>1的字符串

显然,前两种情况为递归的终结状态,子表为空表或只含一个原子结点,后一种情况为递归调用

Status CreateGList (GList &L, SString S) {//采用头尾链表存储结构,由广义表的书写形式串S创建广义表L。设 emp="()"if (StrCompare(S, emp))L=NULL//创建空表else {if (! (L = (GList) malloc (sizeof (GLNode)))) exit (OVERFLOW); //建表结点if (StrLength(S)==1){L->tag = ATOM; L->atom =S;}// 创建单原子广义表else {L->tag = LIST; p = L;SubString (sub, S, 2, Strength(S)2) ;// 脱外层括号do// 重复建n 个子表sever(sub,hsub);// 从 sub中分离出表头串hsubCreateGList(p->ptr. hp,hsub);q = p;if (!StrEmpty(sub)){// 表尾不空if (!(p = (GLode * ) malloc (sizeof (GLNode))))exit (OVERFLOW) ;p->tag = LIST; q->ptr.tp = p;}//if}while (! StrEmpty (sub)) ;q—>ptr. tp = NULL;}//else} // elsereturn OK;
}// CreateGListStatus sever(SString &str, SString &hstr) {// 将非空串 str 分割成两部分:hsub 为第一个‘,’之前的子串,str 为之后的子串n= StrLength(str); i=0;k=0//k记尚未配对的左括号个数do {// 搜索最外层的第一个逗号++i;SubString(ch, str,i,1);if(ch =='(')  十十k;else if (ch==‘)’)  --k;} while (i<n && (ch! =','|| k! =0));if (i<n){SubString (hstr, str, 1, i—1)SubString(str, str, i+1, n—i)} else {StrCopy (hstr, str); ClearString(str) }
} // sever

相关文章:

数据结构-数组(稀疏矩阵转置)和广义表

目录 1、数组定义 1&#xff09;数组存储地址计算示例①行优先②列优先 2&#xff09;稀疏矩阵的转置三元组顺序表结构定义 ①普通矩阵转置②三元组顺序表转置稀疏矩阵③稀疏矩阵的快速转置 3&#xff09;十字链表结构定义 2、广义表定义 1&#xff09;基本操作①GetHead②GetT…...

Java中的远程方法调用——RPC详解

1. 什么是RPC&#xff1f; RPC基础介绍 Java中的远程方法调用&#xff08;Remote Procedure Call&#xff0c;RPC&#xff09;是一种允许一个程序调用另一台计算机上方法的技术&#xff0c;就像在本地一样。RPC的核心思想是简化分布式计算&#xff0c;让我们可以跨网络调用远程…...

【kafka】大数据编写kafka命令使用脚本,轻巧简洁实用kafka

kafka是大数据技术中举足轻重的技术&#xff0c;市面上也有很多kafka的ui界面&#xff0c;但是都会占用比较大的内存和性能&#xff0c;这里我编写好了一个fakfa的脚本集成了kafka常见的命令使用。脚本资源放在文章顶部可自行拿取。 《Kafka 命令大全系统脚本使用指南》 在大数…...

交换区(Swap Area或Swap Partition)

在操作系统中&#xff0c;交换区&#xff08;Swap Area或Swap Partition&#xff09;扮演着至关重要的角色&#xff0c;主要用于在物理内存&#xff08;RAM&#xff09;不足时提供额外的虚拟内存空间。以下是交换区的主要功能和作用&#xff1a; 一、内存扩展 当系统的物理内…...

Excel 无法打开文件

Excel 无法打开文件 ‘新建 Microsoft Excel 工作表.xlsx",因为 文件格式或文件扩展名无效。请确定文件未损坏&#xff0c;并且文件扩展名与文件的格式匹配。...

MySQL —— Innodb 索引数据结构

文章目录 不用平衡二叉树或红黑树作为索引B树适合作为索引比B树更适合作为索引的结构——B树总结 MySQL 使用 B树索引数据结构&#xff08;因为默认使用 innodb 存储引擎&#xff09; B树&#xff1a;有序数组 平衡多叉树&#xff1b;B树&#xff1a;有序数组链表 平衡多叉树…...

探索C语言数据类型

目录 前言 一、基本数据类型 1.整型&#xff08;Integer&#xff09; 2.浮点型&#xff08;Floating - point&#xff09; 3.字符型&#xff08;Character&#xff09; 4.布尔型&#xff08;Boolean&#xff09; 二、派生数据类型 1.数组&#xff08;Array&#xff09…...

凌晨官宣离婚,他们为何让老粉直呼天塌?

你说的是影视飓风MediaStorm的创始人Tim和小鱼吧&#xff0c;他们确实在11月5日凌晨官宣离婚了。以下是具体介绍&#xff1a;官宣离婚2024年11月5日凌晨&#xff0c;影视飓风MediaStorm的创始人Tim&#xff08;潘天鸿&#xff09;在社交媒体上发文&#xff0c;宣布与小鱼&#…...

Spring Boot 导出 Excel 文件

本文将详细介绍如何使用 Spring Boot 和 Apache POI 实现 Excel 文件的导出功能&#xff0c;帮助开发者快速上手。 1. 准备工作 首先&#xff0c;确保你的 Spring Boot 项目已成功创建并运行。接下来&#xff0c;需要在 pom.xml 文件中添加 Apache POI 相关依赖&#xff0c;以…...

HTTPSOK:SSL/TLS证书自动续期工具

HTTPSOK 是一个支持 SSL/TLS 证书自动续期 的工具&#xff0c;旨在简化 SSL 证书的管理&#xff0c;尤其是自动化处理证书续期的工作。对于大多数网站而言&#xff0c;SSL 证书的续期是一项必要但容易被忽视的工作&#xff0c;因为 SSL 证书的有效期通常为 90 天。使用 HTTPSOK…...

Uniapp安装Pinia并持久化(Vue3)

安装pinia 在uni-app的Vue3版本中&#xff0c;Pinia已被内置&#xff0c;无需额外安装即可直接使用&#xff08;Vue2版本则内置了Vuex&#xff09;。 HBuilder X项目&#xff1a;直接使用&#xff0c;无需安装。CLI项目&#xff1a;需手动安装&#xff0c;执行yarn add pinia…...

基于Dpabi和spm12的脑脊液(csf)分割和提取笔记

一、前言 脑脊液&#xff08;csf&#xff09;一直被认为与新陈代谢有重要关联&#xff0c;其为许多神经科学研究提供重要价值&#xff0c;从fMRI图像中提取脑脊液信号可用于多种神经系统疾病的诊断。特别是自2019年Science上那篇著名的csf-BOLD文章发表后&#xff0c;大家都试图…...

【每日一题】2012考研数据结构 - 求字符串链表公共后缀

本篇文章将为大家讲解一道关于链表的经典题目——求两个链表的共同后缀节点。该问题在实际开发中同样具有很大的应用价值&#xff0c;是每一位数据结构学习者不可错过的重要题目。 问题描述 假设我们有一个带头结点的单链表来保存单词&#xff0c;每个节点包含一个字符和指向…...

数据结构和算法-贪心算法01- 认识贪心

贪心算法 什么是贪心算法 一个贪心算法总是做出当前最好的选择&#xff0c;也就是说&#xff0c;它期望通过局部最优选择从而得到全局最优的解决方案。 ​ ----《算法导论》 贪心算法(Greedy Method): 所谓贪心算法就是重复地(或贪婪地)根据一个法则挑选解的一部分。当挑选完毕…...

Bash Shell - 获取日期、时间

1. 使用date获取日期 以下代码将date的执行结果存储在today变量中。date 是获取日期和时间的命令。 选择使用 quotes()或$ #!/bin/bashtodaydate echo $todaytoday$(date) echo $today 2. 使用 Format 输出所需日期和时间 date FORMAT 2.1 "MM-DD-YY" 形式输出…...

runnable和callable区别和底层原理

确实&#xff0c;Runnable 可以直接通过 Thread 类来运行&#xff0c;而 Callable 不能直接用于创建和运行线程。Callable 和 Runnable 都是 Java 中用于定义异步任务的接口&#xff0c;但它们的用法和目的有所不同。 ### Runnable 和 Thread Runnable 是接口&#xff0c;它不返…...

Springboot 整合 Java DL4J 打造自然语言处理之语音识别系统

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

虚幻引擎5(UE5)学习教程

虚幻引擎5&#xff08;UE5&#xff09;学习教程 引言 虚幻引擎5&#xff08;Unreal Engine 5&#xff0c;简称UE5&#xff09;是Epic Games开发的一款强大的游戏引擎&#xff0c;广泛应用于游戏开发、影视制作、建筑可视化等多个领域。UE5引入了许多先进的技术&#xff0c;如…...

从0开始深度学习(26)——汇聚层/池化层

池化层通过减少特征图的尺寸来降低计算量和参数数量&#xff0c;同时增加模型的平移不变性和鲁棒性。汇聚层的主要优点之一是减轻卷积层对位置的过度敏感。 1 最大汇聚层、平均汇聚层 汇聚层和卷积核一样&#xff0c;是在输入图片上进行滑动计算&#xff0c;但是不同于卷积层的…...

兼职发薪系统:高效、便捷的劳务发薪解决方案

在快速发展的数字化时代&#xff0c;企业对于高效、便捷的薪酬发放和管理解决方案的需求日益增长。特别是对于兼职人员众多的企业&#xff0c;如何实现快速、准确的发薪&#xff0c;同时确保员工信息的安全与保密&#xff0c;成为了一个亟待解决的问题。今天&#xff0c;我们将…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...