【python数据结构】多维数组

  • Post author:
  • Post category:python



在程序设计语言中大都提供了数组作为构造数据类型,本章重点讨论数组以及特殊矩阵的


存储





寻址




目录


数组


数组的定义


数组的特点


数组的基本操作


数组的存储结构与寻址


一维数组


二维数组


按行优先存储的寻址


矩阵的压缩存储


特殊矩阵和稀疏矩阵


压缩存储的基本思想


对称矩阵


三角矩阵


下三角矩阵:


上三角矩阵:


对角矩阵


稀疏矩阵


转置操作:


十字链表


本章总结


数组

数组的定义


数组是由一组


类型相同


的数据元素构成的


有序


集合





每个数据元素称为一个数组元素(简称为元素),每个元素受



n



(



n



≥1)





线性关系


的约束,


每个元素在



n



个线性关系中的序号



i



1






i



2


、…、



i




n



称为该元素的下标,并称该数组为



n



维数组。

如上图表示的二维数组中,

元素


a


22


受两个线性关系的约束,在行上有一个行前驱


a


21


和一个行后继


a


23


,在列上有一个列前驱


a


12


和和一个列后继


a


32



数组的特点


  • 元素本身可以具有某种结构,属于同一数据类型;

  • 数组是一个具有固定格式和数量的数据集合。


数组的基本操作



  • 读操作:给定一组下标,读出对应的数组元素;



  • 写操作:给定一组下标,存储或修改与其相对应的数组元素。


读操作和写操作本质上只对应一种操作——


寻址


在数组上一般不能做插入和删除元素的操作,

所以不用预留空间,适合采用顺序存储。


数组的存储结构与寻址


一维数组



设一维数组的下标的范围为闭区间[





l











h





],




每个数组元素占用





c





个存储单元,则其任一元素





a






i





的存储地址可由下式确定:



Loc(





a






i





)=Loc(





a






l





)+(





i











l











c


二维数组



常用的映射方法有两种:













  • 优先:




    先行后列




    ,先存储行号较小的元素,行号相同者先存储列号较小的元素。













  • 优先:




    先列后行




    ,先存储列号较小的元素,列号相同者先存储行号较小的元素。



按行优先存储的寻址





a






ij





前面的元素个数




=阴影部分的面积




=整行数×每行元素个数+本行中





a






ij





前面的元素个数



=(





i







l





1




)×(





h





2






l





2




+1)+(





j











l





2




)


矩阵的压缩存储



特殊矩阵和稀疏矩阵




特殊矩阵:




矩阵中很多值相同的元素并且它们的分布有一定的规律:对称矩阵、三角矩阵、对角矩阵








稀疏矩阵:




矩阵中有很多零元素。



压缩存储的基本思想




⑴ 为多个值




相同




的元素只分配




一个




存储空间;



⑵ 对









元素




不分配




存储空间。



对称矩阵


压缩存储:


存储下三角部分的元素。由于下三角中共有





n





×(





n





+1)/2




个元素,可将这些元素按行存储到一个数组




SA[





n





×(





n





+1)/2]




中。




a






ij





在一维数组中的序号




=阴影部分的面积




=[(i-1)(i-1)+(i-1)]/2 + j  =





i





×(





i





-1)/2+





j









一维数组下标从0开始










a






ij





在一维数组中的下标





k





=





i





×(





i





-1)/2+





j





-1



对于下三角中的元素





a






ij











i











j










,在数组




SA




中的下标





k











i











j





的关系为:





k











i





×(





i





-1)/2+





j





-1








上三角中的元素





a






ij











i











j





),




因为





a






ij











a






ji










则访问和它对应的元素





a






ji





即可,即:





k











j





×




(





j





-1)/2+





i





-1

三角矩阵



压缩存储:只存储上三角(或下三角)部分的元素。



下三角矩阵:




矩阵中任一元素





a






ij





在数组中的下标





k











i











j





的对应关系:

上三角矩阵:



矩阵中任一元素





a






ij





在数组中的下标





k











i











j





的对应关系:

对角矩阵



所有非零元素都集中在以主对角线为中心的带状区域中,除了主对角线和它的上下方若干条对角线的元素外,所有其他元素都为零。



寻址计算方法:



元素





a






ij





在一维数组中的序号




=2 + 3(





i





-2)+(





j











i





+ 2)




=2





i





+





j





-2








一维数组下标从0开始




∴元素





a






ij





在一维数组中的下标





k





=




2





i





+





j





-3

稀疏矩阵



由于稀疏矩阵中的非零元素的分布没有规律,因此




将稀疏矩阵中的每个非零元素表示为









(




行号,列号,非零元素值)




——




三元组



三元组表




:将稀疏矩阵的非零元素对应的三元组所构成的集合,按行优先的顺序排列成一个线性表。

转置操作:




算法1:




直接取,顺序存




(时间复杂度较高)









A





的三元组顺序表中




依次




找第0列、第1列、…直到最后一列的三元组,并将找到的每个三元组的行、列交换后




顺序




存储到





B





的三元组顺序表中。

伪代码:



1. 设置转置后矩阵




B




的行数、列数和非零元个数;



2. 在




B




中设置初始存储位置




pb;



3. for (col=




最小列号;




col<=




最大列号;




col++)



3.1









A




中查找列号为




col




的三元组;



3.2 交换其行号和列号,存入




B









pb




位置;



3.3




pb++;



算法2:




顺序取,直接存。




即在





A





中依次取三元组,交换其行号和列号放到





B










适当




位置。



引入两个数组作为辅助数据结构:



num[nu]:




存储矩阵





A





中某列的非零元素的个数;



cpot




[nu]:




初值表示矩阵





A





中某列的第一个非零元素在




B




中的位置。



num









cpot存在如下递推关系:



cpot




[0]=0;




cpot




[col]=




cpot




[col-1]+num[col-1];   1≤col<nu



将矩阵




A









col




列元素存放在





B





中下标为




cpot




[col]




的位置

伪代码:



1. 设置转置后矩阵




B




的行数、列数和非零元素的个数;



2. 计算




A




中每一列的非零元素个数;



3. 计算




A




中每一列的第一个非零元素在




B




中的下标;



4. 依次取




A




中的每一个非零元素对应的三元组;



4.1 确定该元素在




B




中的下标




pb








4.2




将该元素的行号列号交换后存入




B









pb




的位置;



4.3 预置该元素所在列的下一个元素的存放位置;



十字链表




采用




链接




存储结构存储三元组表,每个非零元素对应的三元组存储为一个链表结点,结构为:



row:




存储非零元素的行号



col:




存储非零元素的列号



item:




存储非零元素的值



right:




指针域,指向同一行中的下一个三元组



down:




指针域,指向同一列中的下一个三元组



稀疏矩阵的压缩存储——十字链表的具体存储方法








1




) 每一行的非零元素按其列号由




right




域链成一个带头结点的循环链表。








2




)每一列的非零元素按其行号由




down




域链成一个带头结点的循环链表。








3




)由于各行列链表头结点




row




域、




col




域和




item




域均为空,行链表头结点只用




right




域,列链表头结点只用




down




域,故这两组链表头结点可以合用。








4




)为了实现对某一行(或某一列)头指针的快速查找,将指向这些头结点的头指针存在一个数组中。

本章总结



版权声明:本文为qq_52057693原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。