GitHub同步更新(已分类):Data_Structure_And_Algorithm-Review
公众号:URLeisure 的复习仓库
公众号二维码见文末
以下是本篇文章正文内容,下面案例可供参考。
特殊矩阵的压缩存储
- 在很多科学工程计算问题中,经常遇到一些特殊的矩阵,这些矩阵的很多值是相同的,有的很多元素是 0,为了节省空间,可以对这类矩阵进行压缩存储。
- 压缩存储:给多个相同的元素分配一个存储空间,元素为 0 的不分配空间。
- 可压缩矩阵:对称矩阵、三角矩阵、对角矩阵、稀疏矩阵等。
特殊矩阵的压缩存储方式
对称矩阵
- 对角矩阵,其元素沿着对角线对称,即 aij = aji。
-
因为上三角和下三角是一样的,因此只储存其中的一个。
-
如果用一维数组存储下(上)三角,则只需要 n(n+1)/2(n代表行数,计算参照求等差数列前n项和)个空间。比全部存储需要的n2个空间少了很多。
-
在上图中,如果只存储其下三角,就将其按行序存储在一维数组 s[ ] 中(下标从 0 开始),如图。
如何寻找 aij 的存储位置?
- 首先,查看存储 aij 前,已经存储了多少个元素。
-
s[ ] 数组的下标从零开始,则 aij 的下标就是 i(i-1)/2 + j - 1。
-
上三角的元素( i < j ),根据对称性,aij = aji,可以直接读取下三角中 aji ( i , j 颠倒)。
-
因此可得出,按行序存储对称矩阵时,aij 的下标为:
-
如果用一维数组 s[] 存储(下标从 0 开始),则 aij 的存储下标 k = aij 前面的元素个数。
-
aij 的存储地址:LOC(aij) = LOC(a11) + k × L。
三角矩阵
- 三角矩阵分为下三角矩阵和上三角矩阵,下三角矩阵是指矩阵的下三角有数据,而其余的都是常数 c 或者为 0.
- 三角矩阵存储时,只需要存储其下三角中的元素,最后一个空间存储常数 c 即可。如果常数都是 0,则不需要存储。
如何寻找 aij 的存储位置?
- 下三角矩阵与对称矩阵的下三角寻找方式相同。
- 上三角矩阵,如图。
-
从图可以求出,aij前共有 i - 1行的所有元素 + j - i个元素。
-
由等差数列公式可得 k = {(i - 1)(2n - i +2)} / 2 + j - i。
对角矩阵
- 对角矩阵又称为带状矩阵,是指在n × n的矩阵中非零元素集中在主对角线(红色虚线)及其两侧,共L(奇数)条对角线的带状区域内,称为L对角矩阵,如图。
-
此为5对角矩阵。
-
L对角矩阵的带宽为L,半带宽 d = (L - 1) / 2。
-
当| i - j | > d 时,aij = 0,为对角矩阵的带状区域外元素;当 | i - j | ≤ d时,aij ≠ 0,为对角矩阵的带状区域内元素。
计算 L 对角矩阵一共有多少个非零元素。
-
如图,将每一行以对角线为中心补零,使每行都达到L个元素。通过等差数列计算得左上角补零个数为 d(d + 1)/2。
-
因此,一共补了 d(d + 1) 个零。所以,带状区域元素个数为 L × n - d(d + 1)。
-
因为 d = (L - 1)/2,所以也可以表达为 ( 2d + 1) × n - d(d + 1)。
对角矩阵的存储方式有两种:
- 按行存储
- 按对角线存储
寻找 aij 的存储位置。
按行存储
-
首先找到 aii 的存储位置,aii 是对角线上的元素,以对角线为中心,左右两侧都是 d 个元素。如图。
-
aii 的存储位置为 (i - 1)× L + d - d。(除了第一行,每行 L 个元素。第一行没存那 d 个零,要减掉)
-
所以,aij 的存储位置为 (i - 1)× L + j - i。
-
无论 aij 在 aii 左边还是右边,公式都一样。
-
按行序,用一维数组(下标从 0 开始)存储 L 对角矩阵,aij 的存储位置为:
按对角线存储
- 存储时,仍然采用“掐头去尾”,开头和结尾的 0 不存储。
-
先找 ai`j的存储位置.
-
其之前有 i` + d 行,每行有 n 个元素,其左侧有 j - 1 个元素,因为最前面的 d 个零没有存储。
-
所以,存储位置为(i`+ d)× n + j - 1 - d。
-
其中 i` = i - j 。
aij 的存储位置为:
稀疏矩阵
-
稀疏矩阵是指非零元素个数较少,且分布没有规律可言的矩阵。
-
一般认为非零元素小于 5% 时,属于稀疏矩阵。当然也没有那么绝对,只要非零元素个数远远小于矩阵元素个数,就可以认为是稀疏矩阵。如图。
存储方式:
- 为了节省空间,只需记录每个非零元素的行、列和数值即可,这就是三元存储法,如图。
广义表
-
广义表是线性表的推广,也称为列表。
-
它是 n(n ≥ 0)个表元素组成的有限序列,记作 LS = (a0 , a1 , a2 , … , an-1)。
-
LS是表名,ai 是表元素,它可以是表(称为子表),也可以是数据元素(称为原子)。n 为表的长度,n = 0 的广义表为空表。
广义表最常见的操作就是求表头
和表尾
。
- 表头 GetHead(L):非空广义表的第一个元素,可以是一个单元素,也可以是一个子表。
- 表尾 GetTail(L):删除表头元素后,余下的元素所构成的表。表尾一定是一个表
- 例如,D = (a , (b) , (a, (b,c,d) ) ),表长为 3,表头为 a,表尾为 ( (b) , (a, (b,c,d) ) )。
关注公众号,感受不同的阅读体验
下期预告: 螺旋矩阵的实现