数组是线性表的推广。一维数组可以看做是一个线性表;二维数组可以看做是线性表的线性表,依次类推。数组一旦被定义,它的维数和维界就不会在改变。一般情况下除了结构的初始化和销毁操作之外,数组仅会存取元素和修改元素的操作,因此数组一般采用顺序结构存储。
一.非压缩存储方式
大多数计算机语言都提供了数组数据类型,逻辑意义上的数组可以采用计算机语言中的数组数据类型进行存储,一个数据的所有元素在内存中占用一段连续的存储空间。
以一维数组
为例,其在内容中的存储形式如下所示:
总结上述形式,发现一维数组中的数据与内存中的存储中的数据存在一定的关系,归纳总结后便可以得到内存中该元素的位置与该元素在一维数组中的位置之间的关系:
LOC(ai)=LOC(a0)+i×L(0≤i<n)
其中L是每个数组元素所占存储单元。
现实生活中,数组不仅仅局限于一维,可能会用到二维,三维,甚至多维结构,但是计算机存储空间却只能是一维结构,那么此时便面临如何存储多维数组的问题。比如下述二维数组:
采用按行优先方式在内存中的形式如下所示:
采用按列优先方式在内存中的形式如下所示:
此时可以发现虽然二维数组没有发生变化,但是内存中的存储方式却千差万别,因此在一组连续存储单元存放数组的数据元素时就进行一次约定,到底时采用那种方式存储的数组。在C语言中,默认按行优先方式在内存中存储,而在FORTRAN语言中则使用的是按列优先方式。
为了方便后续使用,对二维数组归纳便可得到内存中该元素的位置与该元素在二维数组中的位置之间的关系(假设该数组为m行n列,且每个数组元素所占存储单元为L)。
按行优先方式在内存的形式的通项公式: LOC(ai,j)=LOC(a0,0)+[i×(n+1)+j]×L
按列优先方式在内存的形式的通项公式: LOC(ai,j)=LOC(a0,0)+[j×(m+1)+i]×L
二.压缩存储
压缩存储一般指为多个相同的元素只分配一个存储空间,对零元素不分配存储空间,这样做的目的便是节省存储空间。但并不是所有的矩阵都可以采用压缩存储,能够采用压缩存储的矩阵要么元素之间有一定的规律,要么矩阵中存在大量的零元素。若具有许多相同矩阵元素或者令元素,并且这些相同矩阵元素或零元素的分布有一定的规律,这样的矩阵称之为特殊矩阵,常见的特殊矩阵有对称矩阵、上(下)三角矩阵,对角矩阵等。
2.1对称矩阵的压缩存储
若n阶方阵A中的任一个元素满足下述性质
则称为n阶对称矩阵。
根据对称矩阵的性质,很容易发现,对称矩阵必然关于主对角线对称,为了方便存储,只需要存储上三角和主对角线元素或着下三角和主对角线元素便可,而当需要使用的时候,只需要将下三角元素按对角线对称复制到上三角便可。
这里以按行优先的方式存储下三角元素和主对角线元素为例。
其存储在内存中的相对位置如下所示:
因为二维数组(矩阵)可以看成是数组的数组,存储在内存中的形式依旧是一维方式,按照一定的规律排列,此时可以简单的将已经存储在内存中的矩阵A看做是一个一维数组B。这样经过分析见可以发现矩阵A和数组B之间的对应关系。
第1行:1个元素(
a1,1
);
第2行:2个元素(
a2,1,a2,2
);
⋮
第i行:i个元素(
ai,1,ai,2,ai,3,⋮,ai,i
);
⋮
第n行:n个元素(
an,1,an,2,an,3,an,4,⋮,an,n
);
归纳总结便可发现:
对于下三角元素和主对角线元素在数组B中的对应关系为:
注:这里规定数组B下标从0开始,k为数组B的通用下标,表示第k(从0开始标记)个元素
对于上三角元素,因为和下三角元素关于主对角线对称,因此上三角元素在数组B中的对应关系只需将上式的i和j调换下次序便可。总结便有矩阵A与数组B的对称关系,如下所示:
2.2三角矩阵的压缩存储
2.2.1下三角矩阵的压缩存储
方阵A中的上(下)三角中的元素(不包括对角线元素)均为常数或者0,则该矩阵称为下(上)三角矩阵。
对于这样的矩阵,只需要存储下(上)三角中的元素之外,在加一个存储常数的存储空间即可,于是三角矩阵的压缩存储便又变为了对称矩阵的压缩存储形式,这里以下三角矩阵为例:
其内存中的相对关系如下所示:
同样假定一数据B,其与数组B的元素对应关系为:
2.2.2上三角矩阵的压缩存储
同理可得上三角矩阵在内存中的相对关系和与数组B元素的对应关系,如下所示:
在内存中的相对关系:
与数组B的元素对应关系为:
2.3三对角矩阵的压缩存储
三对角矩阵也称为带状矩阵。若n阶方阵A中的任一元素 ai,j 满足下述性质
当 |i−j|>1 时,有 ai,j=0(1≤i,j≤n)
则称为三对角矩阵,如下所示:
在三对角矩阵中,所有非零元素都集中在主对角线为中心的三条对角线的区域中,其他区域的元素都为零。
三对角矩阵同样可以采用压缩存储,将三条对角线上的元素按行优先方式存放在内存中,其相对关系如下所示:
由此便可以计算出矩阵A中的3条对角线的元素 ai,j(1≤i,j≤n,|i−j|≤1) ,在一维数组B中存放的下标为
2.4稀疏矩阵的压缩存储
矩阵元素个数s相对于矩阵中的非零元素t个数来说非常多,即s \gt\gt t的矩阵称为稀疏矩阵。
比如一个100\times 100的矩阵中,仅有少于100个非零元素,这样的矩阵便是稀疏矩阵。
如果采用常规的方法存储稀疏矩阵无疑是非常浪费存储空间的,如果仅存储非零元素,这样便可以极大的节省存储空间,但是在稀疏矩阵中,非零元素并没有规律可言,所有上述的压缩存储方法不再适用。但是如若在存储稀疏矩阵的非零元素时,同时存储其所在行和所在列,那么便可以将稀疏矩阵的非零元素变成一个三元组(行标,列标,值),然后再将其存储,这样便可以极大的节省存储空间,不过也应注意到此种方法使其失去了随机存取的特性。
其存储的三元组如下:
i | j | v |
---|---|---|
0 | 0 | 2 |
1 | 2 | 1 |
2 | 1 | 3 |
3 | 3 | 4 |