总览
一维数组的存储结构
如果下标从1开始,则a[i]的存放地址=LOC +(i-1)*sizeof(ElemType);
二维数组的存储
二维数组也具有随机存储的特性
设起始地址为LOC
在M行N列的二维数组b[M][N]中,若按行优先存储,
则b[i][j]的存储地址的=LOC + (i*N+j) * sizeof(ElemType)
在M行N列的二维数组b[M][N]中,若按列优先存储,
则b[i][j]的存储地址的=LOC + (j*N+i) * sizeof(ElemType)
行优先存储的优点:可以随机存储、
列优先存储
普通矩阵的存储
对普通矩阵存储我们可以采用二维数组存储
-
行优先存储(大多数编程语言,如 C/C++、Java、Python):
position=i*n+j
-
列优先存储(某些语言和库,如 Fortran):
position=j*m+i
普通矩阵的存储通常涉及到计算机内存中的数据结构。在大多数编程语言中,矩阵通常被实现为一维数组或者二维数组。
-
一维数组存储:在这种方法中,矩阵被 flatten 成一个一维数组。例如,一个 2x3 的矩阵:
-
可以被存储为一个一维数组
[1, 2, 3, 4, 5, 6]
。在内存中,这个数组是连续存储的。要访问矩阵中的元素,需要通过特定的公式来计算其在数组中的位置。例如,要访问元素(i, j)
,在列优先存储(Column-major order)中,其在一维数组中的位置是i + j * rows
;在行优先存储(Row-major order)中,其位置是i * cols + j
。 -
二维数组存储:在这种方法中,矩阵被存储为一个二维数组。在大多数编程语言中,这通常是通过数组的数组或者动态分配的二维数组来实现的。例如,在 C 语言中,可以使用
int matrix[2][3]
来声明一个 2x3 的矩阵。在内存中,这个二维数组同样是连续存储的,但是以行或列的顺序。
每种存储方法都有其优缺点。一维数组存储更节省空间,因为不需要存储额外的行或列的指针信息,但是在访问特定元素时可能需要更多的计算。二维数组存储在访问元素时更直观,但是在某些编程语言中可能需要更多的内存来存储额外的指针信息。
对称矩阵的压缩存储
若n阶方阵中任意一个元素都有,则该矩阵为对称矩阵
策略:只存储主队角线+下三角区
按行优先原则将各元素存入一维数组中
数组大小应该设置为 ,简而言之就是一个等差数列求和
,问题:对称矩阵压缩存储后该怎么样才能方便使用?
可以实现一个“映射”函数
矩阵下标—>一维数组下标
i>j(下三角)时
下标为0,从第0行开始元素个数有1个第二行元素个数2个....到最后一行有n个,所以它的元素总数为个,所以我们设置的一维数组大小应该就这么大,然后求aij在一维数组的坐标我们应该算出aij是第几个元素,按照行优先的原则,我们先得出aij前面有多少行,第一行为1,然后最后一行是i-1本身,为什么要-1呢?因为下标是从0开始的,所以转换成一维数组后需要减1如果下标从1开始则bu'xu'y,求出等差数列和为,注意这里i-1才是项数,i是首项加末项由i-1+1得来,然后再算出aij前面有多少列元素,根据推导可得有j个元素,所以,这里-1原理同上
i<j(上三角)时
由于对称矩阵aij=aji ,所以
出题思路:
下标从0开始,先求aij前面有多少列元素,第一列是n元素,第二列n-1一值到最后一列n-(j-1-1),为什么要加1呢?因为,我们求的是i-1,i-1有n-(j-1-1)个元素,接下来再求行元素,根据图不难发现,求行元素只需将i-j便可求出除该元素之外本行有多少行元素,因为下标从0开始,所以最后再加上1得出坐标为
三角矩阵的压缩存储
下三角矩阵:
除了主对角线和下三角区,其余的元素都相同
压缩存储策略:按行优先原则将橙色区元素存入一维数组中。并在最后一个位置存储常量c
映射规律下三角区的规律和对称矩阵的相同,只是访问上三角区的时候我们需要把下标映射到一维数组的最后一个位置
上三角矩阵:
除了主对角线和上三角区,其余的元素都相同
压缩存储策略:按行优先原则将绿色区元素存入一维数组中。并在最后一个位置存储常量c
首先我们确定aij前面有多少行,所以我们需要知道i-1行,第一行是n个,第二行n-1个,所以第n行有n-(i-1),所以第i-1行是n-(i-1-1)=n-i+2,等差数列求和:得知i前面有个元素,我们再来计算j前面有多少列元素,就是j-i,得知j前面有j-i个元素,于是我们得知aij是第个元素,最后-1是因为下标从0开始
三对角矩阵的压缩策略
三对角矩阵是一种特殊的带状矩阵,它在矩阵中只有主对角线、主对角线上方的一条对角线和主对角线下方的一条对角线上的元素是非零的,而其他位置的元素都是零。这种矩阵在数值分析中非常常见,尤其是在求解线性方程组时。
三对角矩阵:当|i-j|>1时,有aij=0 (1<=i,j<=n)
压缩策略:按行优先(或列优先原则,只存储带状部分)
由三队角矩阵可见除第一行和最后一行元素是两个以外其它行元素都是3个所以元素总数是,如果默认下标是0开始,那么最后一个数组的下标则是3n-3
将行号和列号映射为一维数组下标
key:按行优先的原则,aij是第几个元素
求行:前i-1行共有3(i-1)-1个元素
求列:aij是i行第j-i+2个元素(看图推理得出)
求一维数组下标:行列元素相加得k=2i+j-2,若数组下标从0开始,则k=2i+j-3
已知k求aij
求B[k]转换成aij的坐标,首先由于k是数组下标是从0开始的,而题目要求k+1则是从1开始
前i-1行共3(i-1)-1个元素,前i行共有 3i-1
所以得出:
可以理解为i刚好大于等于(k+2)/3 : 向上取整即可满足"刚好"大于等于:
稀疏矩阵的压缩存储
稀疏矩阵:非零元素远远少于矩阵元素的个数
压缩存储策略1:
顺序存储---三元组<行,列,值>
压缩存储策略2:
链式存储---十字链表法