【计算机考研(408)- 数据结构】数组和特殊矩阵

数组和特殊矩阵

数组

数组的定义

数组是由n(n>=1)个相同类型的数据元素构成的有限序列。每个数据元素称为一个数组元素,每个元素在n个线性关系中的序号称之为该元素的下标,下标的取值范围称为数组的维界

数组是[[线性表]]的推广,一维数组可视为一个线性表,二维数组可视为其元素是定长数组的线性表。

数组的存储结构

各数组元素大小相同,且物理上连续存放。

我们用一个 Markdown 表格模拟数组的地址存储结构(ElemType a[7]):

其他a[0]a[1]a[2]a[3]a[4]a[5]a[6]其他
LOCLOC+1

数组元素a[i]的存放地址=LOC+i∗sizeof(ElemType) 数组元素a[i]的存放地址= LOC + i * sizeof(ElemType) 数组元素a[i]的存放地址=LOC+isizeof(ElemType)

每个单元格表示数组元素在内存中的连续存储位置,数组元素之间没有间隔,便于通过下标快速访问。

接下来假设有一个二维数组() ElemType b[2][4],我们可以用一个 Markdown 表格模拟其地址存储结构和逻辑结构:

逻辑结构:

b[0][0]b[0][1]b[0][2]b[0][3]
b[1][0]b[1][1]b[1][2]b[1][3]

但是在内存中,数组是连续的,那么也就有了行优先和列优先的存储方式。

列优先存储结构:

其他b[0][0]b[1][0]b[0][1]b[1][1]b[0][2]b[1][2]b[0][3]b[1][3]其他
LOC+0LOC+1LOC+2LOC+3LOC+4LOC+5LOC+6LOC+7

M行N列的二维数组b[M][N]中,若按列优先存储,则:

b[i][j]的存放地址=LOC+(j∗M+i)∗sizeof(ElemType) b[i][j]的存放地址= LOC + (j * M + i) * sizeof(ElemType) b[i][j]的存放地址=LOC+(jM+i)sizeof(ElemType)

行优先存储结构:

其他b[0][0]b[0][1]b[0][2]b[0][3]b[1][0]b[1][1]b[1][2]b[1][3]其他
LOC+0LOC+1LOC+2LOC+3LOC+4LOC+5LOC+6LOC+7

M行N列的二维数组b[M][N]中,若按行优先存储,则:

b[i][j]的存放地址=LOC+(i∗N+j)∗sizeof(ElemType) b[i][j]的存放地址= LOC + (i * N + j) * sizeof(ElemType) b[i][j]的存放地址=LOC+(iN+j)sizeof(ElemType)

矩阵的存储和特殊矩阵的压缩存储

压缩存储是指为多个值相同的元素只分配一个存储空间,对零元素不分配空间。
特殊矩阵就是指分布有一定规律的矩阵。
压缩存储方法:找出分布规律,把那些呈现规律性分布的、值相同的元素放在同一个存储空间中。

对称矩阵

a1,1a_{1,1}a1,1a1,2a_{1,2}a1,2⋯\cdotsa1,na_{1,n}a1,n
a2,1a_{2,1}a2,1a2,2a_{2,2}a2,2⋯\cdotsa2,na_{2,n}a2,n
⋮\vdots⋮\vdots⋱\ddots⋮\vdots
an,1a_{n,1}an,1an,2a_{n,2}an,2⋯\cdotsan,na_{n,n}an,n

如上所示的矩阵是一个n阶矩阵,若对于任意的i,ji,ji,j,都有ai,j=aj,ia_{i,j}=a_{j,i}ai,j=aj,i,则称之为对称矩阵。其中的元素也可以根据i,j的大小分为三个部门:i=ji=ji=j主对角线,i>ji>ji>j 下三角区,i<ji<ji<j 上三角区。

普通存储:n*n二维数组,因为上下两个三角区数值相同,所以可以压缩存储。

压缩存储策略:只存储主对角线+下三角区(或主对角线+上三角区)

同时我们需要按照行/列优先的原则存入到一个一维数组中,并建立i,j(矩阵下标)与数组下标的映射关系。

以下以行优先为例:

对于i>=j的下标来说,第一个存储的是 i=1,j=1,第二个存储的是 i=2,j=1,接着 2,23,13,23,3。分别映射到了0,1,2,3上面。

根据不难看出,对于i是累加的,比如第一行起始是0,第二行起始是1,到了第三行起始就变为了3。那么其实他就是一个等差数列。

根据等差数列求和公式:n(a1+an)2\frac{n(a_1 + a_n)}{2}2n(a1+an),其中a1=0a_1 = 0a1=0an=i−1a_n = i - 1an=i1n=in = in=i。因此,第iii行的起始下标为i(i−1)2\frac{i(i-1)}{2}2i(i1)。接着我们加上j的偏移量,得到下标为i(i−1)2+j−1\frac{i(i-1)}{2} + j - 12i(i1)+j1。(j-1的原因是因为数组下标从0开始)

至此我们把矩阵中下三角的元素都存储了,正因为ai,j=aj,ia_{i,j} = a_{j,i}ai,j=aj,i,对于上三角的元素,我们直接替换下标即可。

得到最终的下标转换公式如下:

k={(i−1)i2+j−1,当 i≥j(下三角区和主对角线元素)(j−1)j2+i−1,当 i<j(上三角区元素) k = \begin{cases} \frac{(i-1)i}{2} + j-1, & \text{当 } i \geq j \text{(下三角区和主对角线元素)} \\ \frac{(j-1)j}{2} + i-1, & \text{当 } i < j \text{(上三角区元素)} \end{cases} k={2(i1)i+j1,2(j1)j+i1, ij(下三角区和主对角线元素) i<j(上三角区元素)

按照上面的方法,分析列优先:

对于i>=j的下标来说,第一个存储的是 i=1,j=1,第二个存储的是 i=1,j=2,接着 2,21,32,33,3。分别映射到了0,1,2,3上面。

根据等差数列求和公式:n(a1+an)2\frac{n(a_1 + a_n)}{2}2n(a1+an),其中a1=0a_1 = 0a1=0an=j−1a_n = j - 1an=j1n=jn = jn=j。因此,第jjj列的起始下标为j(j−1)2\frac{j(j-1)}{2}2j(j1)。接着我们加上i的偏移量,得到下标为j(j−1)2+i−1\frac{j(j-1)}{2} + i - 12j(j1)+i1。(i-1的原因是因为数组下标从0开始)

至此,我们得到列优先的公式为:

k={j(j−1)2+i−1,if i≥ji(i−1)2+j−1,if i<j k = \begin{cases} \frac{j(j-1)}{2} + i - 1, & \text{if } i \geq j \\ \frac{i(i-1)}{2} + j - 1, & \text{if } i < j \end{cases} k={2j(j1)+i1,2i(i1)+j1,if ijif i<j

对于存储上三角的方法,我不想写了,留给我自己思考去吧

三角矩阵

a1,1a_{1,1}a1,1CCCCCCCCC
a2,1a_{2,1}a2,1a2,2a_{2,2}a2,2CCCCCC
a3,1a_{3,1}a3,1a3,2a_{3,2}a3,2a3,3a_{3,3}a3,3CCC
a4,1a_{4,1}a4,1a4,2a_{4,2}a4,2a4,3a_{4,3}a4,3a4,4a_{4,4}a4,4

下三角矩阵:除了主对角线和下三角区,其余的元素都相同(如表格所示)
上三角矩阵:除了主对角线和上三角区,其余的元素都相同(如表格所示)

压缩存储策略(下三角矩阵为例):按行优先原则将下三角区存入一维数组中。并在最后一个位置存储常量C,上面分析的下三角区存储公式可以直接使用。而常数C的存储位置为n(n+1)/2n(n+1)/2n(n+1)/2

存储下三角矩阵的下标转换公式:

k={(i−1)i2+j−1, if i≥j(下三角区和主对角线元素)n(n+1)2,if i<j(上三角区元素) k = \begin{cases} \frac{(i-1)i}{2} + j - 1, & \ \text{if } i \geq j (下三角区和主对角线元素) \\ \frac{n(n+1)}{2}, & \text{if } i < j (上三角区元素) \end{cases} k={2(i1)i+j1,2n(n+1), if ij(下三角区和主对角线元素)if i<j(上三角区元素)

下面开始分析上三角矩阵的存储,还是上面的策略,常数C的存储位置为n(n+1)/2n(n+1)/2n(n+1)/2

那么对于第i行应当开始存储的位置应该为上i-1行的元素个数,应当为n(i−1)−(i−1)(i−2)2=(i−1)(2n−i+2)2n(i-1)-\frac{(i-1)(i-2)}{2}=\frac{(i-1)(2n-i+2)}{2}n(i1)2(i1)(i2)=2(i1)(2ni+2),其中,n(i−1)n(i-1)n(i1)代表该矩阵第i行之前一共的元素数目,之后的式子代表下三角区的累计数目,对于第j列,应为相对于对角线的偏移量即为(j-i)。

因此我们可以得到存储上三角矩阵的下标转换公式:

k={(i−1)(2n−i+2)2+(j−i)i≤j(上三角区和主对角线元素)n(n+1)2i>j(下三角区元素) k = \begin{cases} \frac{(i-1)(2n-i+2)}{2} + (j-i) & i \leq j (上三角区和主对角线元素) \\ \frac{n(n+1)}{2} & i > j (下三角区元素) \end{cases} k={2(i1)(2ni+2)+(ji)2n(n+1)ij(上三角区和主对角线元素)i>j(下三角区元素)

三对角矩阵

三对角矩阵,又称带状矩阵:当∣i−j∣>1|i-j|>1ij>1时,元素值为0。(1≤i,j≤n)(1\leq i,j\leq n)(1i,jn)

a1,1a_{1,1}a1,1a1,2a_{1,2}a1,20000
a2,1a_{2,1}a2,1a2,2a_{2,2}a2,2a2,3a_{2,3}a2,3000
0a3,2a_{3,2}a3,2a3,3a_{3,3}a3,3a3,4a_{3,4}a3,400
00a4,3a_{4,3}a4,3a4,4a_{4,4}a4,4a4,5a_{4,5}a4,50
000a5,4a_{5,4}a5,4a5,5a_{5,5}a5,5a5,6a_{5,6}a5,6
0000a6,5a_{6,5}a6,5a6,6a_{6,6}a6,6

压缩存储策略:按行优先(或列优先)原则,只存储带状部分

那么按行优先规则,前i-1行的元素个数为3(i−1)−13(i-1)-13(i1)1,第i行的元素个数为3,最后一行的元素个数为2。那么ai,ja_{i,j}ai,j是第i行的第j-i+2(如果下标从1开始,从零开始还要减1)个元素。所以我们得到如下的公式:

k=3(i−1)−1+j−i+2−1=2i+j−3 k=3(i-1)-1+j-i+2-1=2i+j-3 k=3(i1)1+ji+21=2i+j3

接下来我们需要讨论一下逆向,即通过k求i和j:

由一维数组下标 kkk 求矩阵下标 i,ji, ji,j 的方法如下:首先确定行号 iii,由于前 i−1i-1i1 行共 3(i−1)−13(i-1)-13(i1)1 个元素,前 iii 行共 3i−13i-13i1 个元素,因此有 3(i−1)−1<k+1≤3i−13(i-1)-1 < k+1 \leq 3i-13(i1)1<k+13i1,即 i≥k+23i \geq \frac{k+2}{3}i3k+2,向上取整得 i=⌈k+23⌉i = \lceil \frac{k+2}{3} \rceili=3k+2
也可以按照王道书的逻辑,3(i−1)−1≤k<3i−13(i-1)-1 \leq k < 3i-13(i1)1k<3i1,即 i≤k+13+1i \leq \frac{k+1}{3} + 1i3k+1+1,向下取整得 i=⌊k+13⌋+1i = \lfloor \frac{k+1}{3} \rfloor + 1i=3k+1+1。确定 iii 后,前 i−1i-1i1 行共 3(i−1)−13(i-1)-13(i1)1 个元素,第 iii 行的第一个元素下标为 k0=3(i−1)−1k_0 = 3(i-1)-1k0=3(i1)1,所以列号 j=k−k0−2+ij = k - k_0 - 2 + ij=kk02+i。公式总结如下:

i=⌈k+23⌉j=k−[3(i−1)−1]−2+i \begin{aligned} &i = \lceil \frac{k+2}{3} \rceil \\ &j = k - [3(i-1)-1] - 2 + i \end{aligned} i=3k+2j=k[3(i1)1]2+i

或者

i=⌊k+13⌋+1j=k−[3(i−1)−1]−2+i \begin{aligned} &i = \lfloor \frac{k+1}{3} \rfloor + 1 \\ &j = k - [3(i-1)-1] - 2 + i \end{aligned} i=3k+1+1j=k[3(i1)1]2+i

先根据 kkk 计算 iii,再用 iii 计算 jjj,两种取整方式结果一致。

稀疏矩阵

稀疏矩阵:非零元素远远少于矩阵元素的个数

压缩存储策略:顺序存储——三元组<行,列,值>

例如,下面的稀疏矩阵:

004005
030900
000070
020000
000000

其三元组顺序存储形式为:(行、列标从0开始)

i行j列v值
024
055
113
139
247
312

行、列标从1开始

134
165
223
249
357
422

既然有顺序存储,那么会有链式存储的方式。压缩存储策略二:链式存储——十字链表法

一个结点包含五部分内容:行、列、值、指向下一个同列元素的指针、指向下一个同行元素的指针。

还是上面的矩阵,如果给他创建一个十字链表,那么就会得到如下结果(图源王道课PPT):

md1ebaq6.png

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

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

相关文章

Agent架构与工作原理:理解智能体的核心机制

Agent架构与工作原理&#xff1a;深入理解智能体的核心机制 AI Agent的核心组成部分 一个完整的AI Agent通常由以下几个核心模块组成&#xff1a; 1. 规划模块&#xff08;Planning Module&#xff09; 规划模块是Agent的"大脑"&#xff0c;负责制定行动策略。它接收…

解决vscode中vue格式化后缩进太小的问题,并去除分号 - 设置Vetur tabSize从2到4,设置prettier取消分号semi

效果图 左边原来的&#xff0c;右边是设置后的效果 实现步骤 安装插件 Vetur 安装插件 prettier Vscode > 文件 > 首选项 > 设置 搜索vetur > 找到比较下面的“Vetur > Format > Options: Tab Size” > 设置缩进为4 在附近找到“Vetur > Format: De…

计算机发展史:电子管时代的辉煌与局限

在计算机的发展历程中&#xff0c;电子管时代犹如一颗璀璨的流星&#xff0c;短暂却耀眼。它接过了机械计算装置的接力棒&#xff0c;以电子管为核心元件&#xff0c;开启了计算机的电子化征程&#xff0c;为后续的计算机发展奠定了坚实的基础。这段从 20 世纪 40 年代到 50 年…

div和span区别

区别1区别2App.vue代码 <template><div class"container"><h1>&#x1f3af; DIV 和 SPAN 标签的区别演示</h1><!-- 第一部分&#xff1a;基本区别演示 --><section class"demo-section"><h2>&#x1f4e6; 1. …

channel_up和lane_up

一、channel_up 1.当aurora通道完成初始化&#xff0c;channel准备发送或者接收数据的时候拉高 2.channel_up属于协议的链路层 3.当所有的通道的lane_up都成功拉高&#xff0c;并且完成通道绑定channel bonding,就拉高channel_up二、lane_up 1.lane初始化成功后拉高&#xff1b…

GDPR合规团队协作软件:保障企业数据安全的关键

随着数据隐私问题日益成为全球关注的焦点&#xff0c;GDPR&#xff08;General Data Protection Regulation&#xff0c;通用数据保护条例&#xff09; 的实施成为企业在数据管理中的一项重要法律要求。特别是对于需要在团队之间协作并共享信息的企业来说&#xff0c;选择合规的…

【图像质量评价指标】信噪比(Signal-to-Noise Ratio,SNR)

文章目录一、基本定义二、判断图像信噪比是否过低&#xff08;经验值&#xff0c;仅供参考&#xff09;三、SNR与图像质量指标关系四、评估方法 代码复现 —— 评估一张图像的信噪比&#xff08;1&#xff09;有参考图像&#xff08;推荐&#xff09;&#xff08;2&#xff09…

Java 实现 TCP 一发一收通信

在网络编程中&#xff0c;TCP&#xff08;传输控制协议&#xff09;凭借其可靠传输的特性&#xff0c;成为需要确保数据完整性场景的核心选择。本文将基于一段 Java 代码实例&#xff0c;全面解析 TCP 单向通信的实现逻辑&#xff0c;帮助开发者掌握 TCP 编程的基础框架与底层原…

docker-compose启动前后端分离项目(单机)

&#x1f31f;docker-compose启动前后端 &#x1f4c1;准备文件 xzs-mysql.sql&#xff08;数据库脚本&#xff09;xzs-3.9.0.jar&#xff08;后端代码&#xff09;application-prod.yml&#xff08;后端配置文件&#xff09;entry.sh&#xff08;后端启动脚本&#xff09;exam…

有关Mysql数据库的总结

MySQL概念MySQL的理论知识概念数据库就是用来存储和管理数据的仓库&#xff01;数据库分类层次型数据库树型结构&#xff0c;一个子记录可以有一个父记录&#xff0c;一个父记录可以有多个子记录&#xff0c;类似一个二叉树&#xff0c;但是一个父节点可以不止两个子节点&#…

复制docker根目录遇到的权限问题

环境 ubuntu20.04, 普通用户使用sudo权限。 需求 linux系统上&#xff0c;默认的docker跟目录在/var/lib/docker目录下&#xff0c;但是根分区太小。想要将docker根目录挪到其它磁盘&#xff0c;防止以后镜像和容器增加后磁盘满了。 操作 先停止所有docker容器&#xff0c;然后…

git-子仓操作

为什么为什么要将代码仓作为子模块&#xff1f;有什么优势&#xff1f;精确版本控制&#xff1a;父仓记录子仓的commit哈希值&#xff0c;确保代码版本固定&#xff0c;避免隐式升级导致的兼容性问题模块化管理&#xff1a;将独立仓库作为子模块嵌入父仓&#xff0c;实现代码物…

代数——第5章——线性算子之应用(Michael Artin)

第 5 章 线性算子之应用 (Applications of Linear Operators) By relieving the brain from all unnecessary work, a good notation sets it free to concentrate on more advanced problems.( 通过减轻大脑所有不必要的工作&#xff0c;良好的符号可以让大脑集中精力解决…

Pytorch02:深度学习基础示例——猫狗识别

一、第三方库介绍库/模块功能torch提供张量操作、自动求导、优化算法、神经网络模块等基础设施。torchvision计算机视觉工具集&#xff0c;提供预训练模型、数据集、图像转换等功能。datasets (torchvision)用于加载常见数据集&#xff08;如 ImageNet、CIFAR-10、MNIST&#x…

spring简单项目实战

项目路径 modelspackage com.qcby.demo1;import com.qcby.service.UserService; import com.qcby.service.UserServiceImpl;public class Dfactory {public UserService createUs(){System.out.println("实例化工厂的方式...");return new UserServiceImpl();} }pack…

ServBay for Windows 1.4.0 发布:新增MySQL、PostgreSQL等数据库自定义配置

各位 Windows 平台的开发者们&#xff0c; ServBay 始终致力于为您打造一个强大、高效且灵活的本地开发环境。距离上次更新仅过去短短一周&#xff0c;经过我们技术团队的快速开发&#xff0c;我们正式推出了 ServBay for Windows 1.4.0 版本。 专业开发者不仅需要一个能用的环…

python网络爬虫小项目(爬取评论)超级简单

python网络爬虫小项目&#xff08;爬取评论&#xff09;超级简单 学习python网络爬虫的完整路径&#xff1a; &#xff08;第一章&#xff09; python网络爬虫(第一章/共三章&#xff1a;网络爬虫库、robots.txt规则&#xff08;防止犯法&#xff09;、查看获取网页源代码)-…

本周大模型新动向:奖励引导、多模态代理、链式思考推理

点击蓝字关注我们AI TIME欢迎每一位AI爱好者的加入&#xff01;01Iterative Distillation for Reward-Guided Fine-Tuning of Diffusion Models in Biomolecular Design本文提出了一种用于生物分子设计中奖励引导生成的扩散模型微调框架。扩散模型在建模复杂、高维数据分布方面…

JAVA+AI教程-第三天

我将由简入繁&#xff0c;由零基础到详细跟大家一起学习java---------------------------------------------------------------------01、程序流程控制&#xff1a;今日课程介绍02、程序流程控制&#xff1a;if分支结构if分支有三种形式&#xff0c;执行顺序就是先执行if&…

自定义命令行解释器shell

目录 一、模块框架图 二、实现目标 三、实现原理 四、全局变量 五、环境变量函数 六、初始化环境变量表函数 七、输出命令行提示符模块 八、提取命令输入模块 九、填充命令行参数表模块 十、检测并处理内建命令模块 十一、执行命令模块 十二、源码 一、模块框架图…