特殊矩阵的压缩存储
作者:互联网
文章目录
数组的存储结构
一个数组的所有元素在内存中是占用一段连续的存储空间的。
<1>一维数组
以一维数组
A
[
0...
n
−
1
]
A[0...n-1]
A[0...n−1]为例,其存储结构关系式为:
L
O
C
(
a
i
)
=
L
O
C
(
a
0
)
+
(
i
)
×
L
(
0
≤
i
<
n
)
LOC(a_i) = LOC(a_0)+(i)×L \quad(0≤i<n)
LOC(ai)=LOC(a0)+(i)×L(0≤i<n)
其中,
L
L
L是每个数组元素所占的存储单元。
例如,对一个一维数组
A
[
n
]
A[n]
A[n],其存储的首地址为100,每个元素占一个存储单元,求
A
[
14
]
A[14]
A[14]的存储位置?
A
[
14
]
A[14]
A[14]的存储位置为:
100
+
14
×
1
=
114
100+14×1 = 114
100+14×1=114
<2>多维数组
对于多维数组,有两种映射方法:按行优先和按列优先。
以二维数组为例,按行优先存储的基本思想是:先行后列。
先存储行号较小的元素,行号相等先存储列号较小的元素。
设二维数组行下标与列下标的范围分别为
[
l
1
,
h
1
]
[l1,h1]
[l1,h1],
[
l
2
,
h
2
]
[l2,h2]
[l2,h2],则存储结构关系式为:
L
O
C
(
a
i
,
j
)
=
L
O
C
(
a
l
1
,
l
2
)
+
[
(
i
−
l
1
)
×
(
h
2
−
l
2
+
1
)
+
(
j
−
l
2
)
]
×
L
LOC(a_{i,j}) = LOC(a_{l_1,l_2}) + [(i-l_1)×(h_2-l_2+1) + (j-l_2)]×L
LOC(ai,j)=LOC(al1,l2)+[(i−l1)×(h2−l2+1)+(j−l2)]×L
若
l
1
l_1
l1 和
l
2
l_2
l2 的值均为0 ,即从
A
[
0
]
[
0
]
A[0][0]
A[0][0]开始,上式变为
L
O
C
(
a
i
,
j
)
=
L
O
C
(
a
0
,
0
)
+
[
i
×
(
h
2
+
1
)
+
j
)
]
×
L
LOC(a_{i,j}) = LOC(a_{0,0}) + [i×(h_2+1) + j)]×L
LOC(ai,j)=LOC(a0,0)+[i×(h2+1)+j)]×L
以二维数组为例,按列优先存储的基本思想是:先列后行。
先存储列号较小的元素,列号相等先存储行号较小的元素。
设二维数组行下标与列下标的范围分别为
[
l
1
,
h
1
]
[l1,h1]
[l1,h1],
[
l
2
,
h
2
]
[l2,h2]
[l2,h2],则存储结构关系式为:
L
O
C
(
a
i
,
j
)
=
L
O
C
(
a
l
1
,
l
2
)
+
[
(
j
−
l
2
)
×
(
h
1
−
l
1
+
1
)
+
(
i
−
l
1
)
]
×
L
LOC(a_{i,j}) = LOC(a_{l_1,l_2}) + [(j-l_2)×(h_1-l_1+1) + (i-l_1)]×L
LOC(ai,j)=LOC(al1,l2)+[(j−l2)×(h1−l1+1)+(i−l1)]×L
若
l
1
l_1
l1 和
l
2
l_2
l2 的值均为0 ,即从
A
[
0
]
[
0
]
A[0][0]
A[0][0]开始,上式变为
L
O
C
(
a
i
,
j
)
=
L
O
C
(
a
0
,
0
)
+
[
j
×
(
h
1
+
1
)
+
i
)
]
×
L
LOC(a_{i,j}) = LOC(a_{0,0}) + [j×(h_1+1) + i)]×L
LOC(ai,j)=LOC(a0,0)+[j×(h1+1)+i)]×L
特殊矩阵的压缩存储
压缩存储:指为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间。其目的是为了节省存储空间。
特殊矩阵:指具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的分布有一定规律性的矩阵。常见的特殊矩阵有对称矩阵、上(下)三角矩阵、对角矩阵等。
对称矩阵
若对一个 n n n 阶方阵 A [ 1... n ] [ 1... n ] A[1...n][1...n] A[1...n][1...n]中的任意一个元素 a i , j a_{i,j} ai,j都有 a i , j a_{i,j} ai,j = a j , i ( 1 ≤ i , j ≤ n ) a_{j,i} \ (1≤i,j≤n) aj,i (1≤i,j≤n),则称其为对称矩阵。
对于 n n n阶方阵,其中的元素可以划分为3个部分,即上三角区、主对角线和下三角区。
对于 n n n阶对称矩阵,上三角区的所有元素和上三角区的对应元素相同,若仍采用二维数组存放,则会浪费几乎一半的空间,为此,将对称矩阵 A [ 1... n ] [ 1... n ] A[1...n][1...n] A[1...n][1...n]存放在一维数组 B [ n ( n + 1 ) / 2 ] B[n(n+1)/2] B[n(n+1)/2]中,即元素 a i , j a_{i,j} ai,j存放在 b k b_k bk中。只存放主对角线和下三角区(或上三角区)的元素,采用行优先存储。
那么在数组B中,位于元素
a
i
,
j
(
i
≥
j
)
a_{i,j}(i≥j)
ai,j(i≥j)前面的元素个数为:
第1行:(
a
1
,
1
a_{1,1}
a1,1) 1个元素
第2行:(
a
2
,
1
a_{2,1}
a2,1,
a
2
,
2
a_{2,2}
a2,2) 2个元素
第3行:(
a
3
,
1
a_{3,1}
a3,1,
a
3
,
2
a_{3,2}
a3,2,
a
3
,
3
a_{3,3}
a3,3) 3个元素
……
第
i
i
i-1行:(
a
i
−
1
,
1
a_{i-1,1}
ai−1,1,
a
i
−
1
,
2
a_{i-1,2}
ai−1,2,…,
a
i
−
1
,
i
−
1
a_{i-1,i-1}
ai−1,i−1)
i
i
i-1个元素
第
i
i
i行:(
a
i
,
1
a_{i,1}
ai,1,
a
i
,
2
a_{i,2}
ai,2,…,
a
i
,
j
−
1
a_{i,j-1}
ai,j−1)
j
j
j-1个元素
那么,元素 a i , j a_{i,j} ai,j 在数组 B B B中的下标 k = 1 + 2 + . . . + ( i − 1 ) + ( j − 1 ) = i ( i − 1 ) / 2 + j − 1 k = 1+2+...+(i-1)+(j-1) = i(i-1)/2+j-1 k=1+2+...+(i−1)+(j−1)=i(i−1)/2+j−1(数组下标从0开始)
因此,元素下标之间的对应关系如下:
k
=
{
i
(
i
−
1
)
2
+
j
−
1
,
i
≥
j
(
下
三
角
区
和
主
对
角
线
元
素
)
j
(
j
−
1
)
2
+
i
−
1
,
i
<
j
(
上
三
角
区
元
素
a
i
,
j
=
a
j
,
i
)
k=\begin{cases} \frac{i(i-1)}{2}+j-1, \quad i≥j\ (下三角区和主对角线元素)\\ \\ \frac{j(j-1)}{2}+i-1, \quad i<j\ (上三角区元素a_{i,j}=a_{j,i}) \end{cases}
k=⎩⎪⎨⎪⎧2i(i−1)+j−1,i≥j (下三角区和主对角线元素)2j(j−1)+i−1,i<j (上三角区元素ai,j=aj,i)
若对称矩阵的压缩存储存放上三角区和主对角线的元素(按行优先),那么
那么在数组B中,位于元素
a
i
,
j
(
i
≤
j
)
a_{i,j}(i≤j)
ai,j(i≤j)前面的元素个数为:
第1行:(
a
1
,
1
a_{1,1}
a1,1,
a
1
,
2
a_{1,2}
a1,2,…,
a
1
,
n
a_{1,n}
a1,n)
n
n
n个元素
第2行:(
a
2
,
2
a_{2,2}
a2,2,
a
2
,
3
a_{2,3}
a2,3,…,
a
2
,
n
a_{2,n}
a2,n)
n
n
n-1个元素
第3行:(
a
3
,
3
a_{3,3}
a3,3,
a
3
,
4
a_{3,4}
a3,4,…,
a
3
,
n
a_{3,n}
a3,n)
n
n
n-2个元素
……
第
i
i
i-1行:(
a
i
−
1
,
i
−
1
a_{i-1,i-1}
ai−1,i−1,
a
i
−
1
,
i
a_{i-1,i}
ai−1,i,…,
a
i
−
1
,
n
a_{i-1,n}
ai−1,n)
n
n
n-
i
i
i+2个元素
第
i
i
i行:(
a
i
,
i
a_{i,i}
ai,i,
a
i
,
i
+
1
a_{i,i+1}
ai,i+1,…,
a
i
,
j
−
1
a_{i,j-1}
ai,j−1)
j
j
j-
i
i
i个元素
那么,元素 a i , j a_{i,j} ai,j 在数组 B B B中的下标 k = n + ( n − 1 ) + . . . + ( n − i + 2 ) + ( j − i ) = ( i − 1 ) ( 2 n − i + 2 ) / 2 + j − i k = n+(n-1)+...+(n-i+2)+(j-i) = (i-1)(2n-i+2)/2+j-i k=n+(n−1)+...+(n−i+2)+(j−i)=(i−1)(2n−i+2)/2+j−i(数组下标从0开始)
因此,元素下标之间的对应关系如下:
k
=
{
(
i
−
1
)
(
2
n
−
i
+
2
)
2
+
j
−
i
,
i
≥
j
(
上
三
角
区
和
主
对
角
线
元
素
)
(
j
−
1
)
(
2
n
−
j
+
2
)
2
+
i
−
j
,
i
<
j
(
下
三
角
区
元
素
a
i
,
j
=
a
j
,
i
)
k=\begin{cases} \frac{(i-1)(2n-i+2)}{2}+j-i, \quad i≥j\ (上三角区和主对角线元素)\\ \\ \frac{(j-1)(2n-j+2)}{2}+i-j, \quad i<j\ (下三角区元素a_{i,j}=a_{j,i}) \end{cases}
k=⎩⎪⎨⎪⎧2(i−1)(2n−i+2)+j−i,i≥j (上三角区和主对角线元素)2(j−1)(2n−j+2)+i−j,i<j (下三角区元素ai,j=aj,i)
三角矩阵
下三角矩阵中,上三角区的所有元素均为同一常量。
其存储思想与对称矩阵一致,不同之处在于存储完下三角区和主对角线上的元素之后,紧接着存储对角线上方的常量一次,故将下三角矩阵
A
[
1...
n
]
[
1...
n
]
A[1...n][1...n]
A[1...n][1...n]存放在一维数组
B
[
n
(
n
+
1
)
/
2
+
1
]
B[n(n+1)/2+1]
B[n(n+1)/2+1]中(按行优先)。
元素下标之间的对应关系为:
k
=
{
i
(
i
−
1
)
2
+
j
−
1
,
i
≥
j
(
下
三
角
区
和
主
对
角
线
元
素
)
n
(
n
+
1
)
2
,
i
<
j
(
上
三
角
区
元
素
)
k=\begin{cases} \frac{i(i-1)}{2}+j-1, \quad i≥j\ (下三角区和主对角线元素)\\ \\ \frac{n(n+1)}{2}, \quad i<j\ (上三角区元素) \end{cases}
k=⎩⎪⎨⎪⎧2i(i−1)+j−1,i≥j (下三角区和主对角线元素)2n(n+1),i<j (上三角区元素)
上三角矩阵中,下三角区的所有元素均为同一常量。
与下三角矩阵的存储一致,存储完上三角区和主对角线上的元素之后,紧接着存储下三角区的常量一次,故将下三角矩阵
A
[
1...
n
]
[
1...
n
]
A[1...n][1...n]
A[1...n][1...n]存放在一维数组
B
[
n
(
n
+
1
)
/
2
+
1
]
B[n(n+1)/2+1]
B[n(n+1)/2+1]中(按行优先)。
元素下标之间的对应关系为:
k
=
{
(
i
−
1
)
(
2
n
−
i
+
2
)
2
+
j
−
i
,
i
≥
j
(
上
三
角
区
和
主
对
角
线
元
素
)
n
(
n
+
1
)
2
,
i
<
j
(
下
三
角
区
元
素
)
k=\begin{cases} \frac{(i-1)(2n-i+2)}{2}+j-i, \quad i≥j\ (上三角区和主对角线元素)\\ \\ \frac{n(n+1)}{2}, \quad i<j\ (下三角区元素) \end{cases}
k=⎩⎪⎨⎪⎧2(i−1)(2n−i+2)+j−i,i≥j (上三角区和主对角线元素)2n(n+1),i<j (下三角区元素)
三对角矩阵
对角矩阵也称为带状矩阵。对角矩阵的概念:
设有一个
n
×
n
n×n
n×n的矩阵
A
A
A,对于矩阵
A
A
A中的任意元素
a
i
,
j
a_{i,j}
ai,j,当
∣
i
−
j
∣
>
1
|i-j|>1
∣i−j∣>1时有
a
i
,
j
=
0
a_{i,j}=0
ai,j=0,这样的矩阵称为三对角矩阵。
[
a
1
,
1
a
1
,
2
a
2
,
1
a
2
,
2
a
2
,
3
a
3
,
2
a
3
,
3
a
3
,
4
⋱
⋱
⋱
a
n
−
1
,
n
−
2
a
n
−
1
,
n
−
1
a
n
−
1
,
n
a
n
,
n
−
1
a
n
,
n
]
\begin{bmatrix} {a_{1,1}}&\quad{a_{1,2}}&&&&&\\ {a_{2,1}}&\quad{a_{2,2}}&\quad{a_{2,3}}&&&\\ &\quad{a_{3,2}}&\quad{a_{3,3}}&{a_{3,4}}&&\\ \\ &&{\ddots}&{\ddots}&{\ddots}\\ &&&{a_{n-1,n-2}}&{a_{n-1,n-1}}&{a_{n-1,n}}&\\ &&&&{a_{n,n-1}}&{a_{n,n}}\\ \end{bmatrix}
⎣⎢⎢⎢⎢⎢⎢⎢⎢⎡a1,1a2,1a1,2a2,2a3,2a2,3a3,3⋱a3,4⋱an−1,n−2⋱an−1,n−1an,n−1an−1,nan,n⎦⎥⎥⎥⎥⎥⎥⎥⎥⎤
三对角矩阵的压缩存储:
在三对角线矩阵中,除了主对角线及在主对角线上下最邻近的两条对角线上的元素外,所有其他元素均为0。为了节省存储空间,只存储主对角线及其上、下两侧次对角线上的元素外,其他零元素一律不存储。
同样需要用一个一维数组 B B B来存储三对角矩阵中位于三对角线上的元素。同样要区分两种存储方式:即行优先方式和列优先方式。
若将三对角线矩阵
A
A
A中的元素按行优先方式存放在一维数组
B
B
B中,则
那么在数组B中,位于元素
a
i
,
j
(
i
≤
j
)
a_{i,j}(i≤j)
ai,j(i≤j)前面的元素个数为:
第1行:(
a
1
,
1
a_{1,1}
a1,1,
a
1
,
2
a_{1,2}
a1,2) 2个元素
第2行:(
a
2
,
1
a_{2,1}
a2,1,
a
2
,
2
a_{2,2}
a2,2,
a
2
,
3
a_{2,3}
a2,3) 3个元素
……
第
i
i
i-1行:(
a
i
−
1
,
i
−
2
a_{i-1,i-2}
ai−1,i−2,
a
i
−
1
,
i
−
1
a_{i-1,i-1}
ai−1,i−1,
a
i
−
1
,
i
+
1
a_{i-1,i+1}
ai−1,i+1) 3个元素
第
i
i
i行:(
a
i
,
i
−
1
a_{i,i-1}
ai,i−1,…,
a
i
,
j
−
1
a_{i,j-1}
ai,j−1)
j
j
j-
i
i
i+1个元素
那么,元素 a i , j a_{i,j} ai,j 在数组 B B B中的下标 k = 2 + 3 ( i − 2 ) + j − i + 1 = 2 i + j − 3 k = 2+3(i-2)+j-i+1 = 2i+j-3 k=2+3(i−2)+j−i+1=2i+j−3(数组下标从0开始),那么就有 { i = ⌊ ( k + 1 ) / 3 + 1 ⌋ j = k − 2 i + 3 \begin{cases} i=\lfloor (k+1)/3+1\rfloor\\ \\ j=k-2i+3\\ \end{cases} ⎩⎪⎨⎪⎧i=⌊(k+1)/3+1⌋j=k−2i+3
稀疏矩阵
若一个矩阵中的非零元素个数远远小于矩阵元素总数,则称该矩阵为稀疏矩阵。
稀疏矩阵的存储:
若用常规二维数组的方法来存储系数矩阵,则相当浪费存储空间,因此对稀疏矩阵仅存储非零元素。
但通常非零元素的分布没有规律,故不仅要存储非零元素的值,还要存储它所在的行和列。因此,可用一个三元组(行标,列标,值)来存储稀疏矩阵。
此外,稀疏矩阵也可用链接存储。采用十字链表表示,它为每个非零元素结点附带了两个链接指针:
- 一个指示同一行下一个非零元素结点(行指针)
- 另一个指示同一列下一个非零元素结点(列指针)
在狮子链表中,每一个三元组结点按照矩阵元素所在行号
i
i
i和列号
j
j
j链接入第
i
i
i个行链表和第
j
j
j个列链表中,即处于所在的行链表和列链表的交汇处。
标签:...,存储,ai,压缩,元素,矩阵,三角区 来源: https://blog.csdn.net/weixin_44162361/article/details/121643293