408答疑
文章目录
三、数组和特殊矩阵
【注】
不建议背公式,会自己推导才有用!!!
1、数组的定义
数组的定义
数组是由 n ( n ⩾ 1 ) n (n \geqslant 1) n(n⩾1) 个相同类型的数据元素构成的有限序列,每个数据元素称为一个数组元素,每个元素在 n n n 个线性关系中的序号称为该元素的下标,下标的取值范围称为数组的维界。
数组与线性表的关系
数组是线性表的推广。一维数组可视为一个线性表;二维数组可视为其元素是定长数组的线性表,以此类推。数组一旦被定义,其维数和维界就不再改变。因此,除结构的初始化和销毁外,数组只会有存取元素和修改元素的操作。
2、数组的存储结构
数组的存储结构
大多数计算机语言都提供了数组数据类型,逻辑意义上的数组可采用计算机语言中的数组数据类型进行存储,一个数组的所有元素在内存中占用一段连续的存储空间。
一维数组的存储结构关系式
以一维数组
A
[
0...
n
−
1
]
A[0...n-1]
A[0...n−1] 为例,其存储结构关系式为:
LOC
(
a
i
)
=
LOC
(
a
0
)
+
i
×
L
(
0
⩽
i
<
n
)
\text{LOC}(a_i) = \text{LOC}(a_0) + i \times L \quad (0 \leqslant i < n)
LOC(ai)=LOC(a0)+i×L(0⩽i<n)
其中,
L
L
L 是每个数组元素所占的存储单元。
二维数组的存储结构关系式
对于多维数组,有两种映射方法:按行优先和按列优先。
- 按行优先存储的基本思想是:先行后列,先存储行号较小的元素,行号相等先存储列号较小的元素。设二维数组的行下标与列下标的范围分别为
[
0
,
h
1
]
[0, h_1]
[0,h1] 与
[
0
,
h
2
]
[0, h_2]
[0,h2],则存储结构关系式为:
LOC ( a i , j ) = LOC ( a 0 , 0 ) + [ i × ( h 2 + 1 ) + j ] × L \text{LOC}(a_{i,j}) = \text{LOC}(a_{0,0}) + [i \times (h_2 + 1) + j] \times L LOC(ai,j)=LOC(a0,0)+[i×(h2+1)+j]×L
- 按列优先存储时,得出存储结构关系式为:
LOC ( a i , j ) = LOC ( a 0 , 0 ) + [ j × ( h 1 + 1 ) + i ] × L \text{LOC}(a_{i,j}) = \text{LOC}(a_{0,0}) + [j \times (h_1 + 1) + i] \times L LOC(ai,j)=LOC(a0,0)+[j×(h1+1)+i]×L
二维数组转为一维数组
将二维数组的元素转换到一维数组进行存储,因此有一个映射关系。根据存储方式的不同,映射关系也不同。
- 行优先: a [ i ] [ j ] a[i][j] a[i][j] 在一维数组的位置: Loc = Loc ( a [ 0 ] [ 0 ] ) + i × col + j \text{Loc} = \text{Loc}(a[0][0]) + i \times \text{col} + j Loc=Loc(a[0][0])+i×col+j,需要注意加的是元素个数,并非单个字节。
- 列优先: a [ i ] [ j ] a[i][j] a[i][j] 在一维数组的位置: Loc = Loc ( a [ 0 ] [ 0 ] ) + j × row + i \text{Loc} = \text{Loc}(a[0][0]) + j \times \text{row} + i Loc=Loc(a[0][0])+j×row+i,需要注意加的是元素个数,并非单个字节。
3、特殊矩阵的压缩存储
基本概念
压缩存储
指为多个值相同的元素只分配一个存储空间,对零元素不分配空间。
对称矩阵
指具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的分布有一定规律性的矩阵。常见的特殊矩阵有对称矩阵、上(下)三角矩阵、对角矩阵等。
特殊矩阵的压缩存储方法
找出特殊矩阵中值相同的矩阵元素的分布规律,把那些呈规律性分布的、值相同的多个矩阵元素压缩存储到一个存储空间中。
对称矩阵
定义
若对一个 n n n 阶矩阵 A A A 中的任意一个元素 a i , j a_{i,j} ai,j 都有 a i , j = a j , i ( 1 ⩽ i , j ⩽ n ) a_{i,j} = a_{j,i} (1 \leqslant i, j \leqslant n) ai,j=aj,i(1⩽i,j⩽n),则称其为对称矩阵。其中的元素可以划分为 3 个部分,即上三角区、主对角线和下三角区。
对称矩阵的压缩存储结构
对于 n n n 阶对称矩阵,上三角区的所有元素和下三角区的对应元素相同,若仍采用二维数组存放,则会浪费几乎一半的空间,为此将 n n n 阶对称矩阵 A A A 存放在一维数组 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 B B 中,位于元素 a i , j ( i ⩾ j ) a_{i,j} (i \geqslant j) ai,j(i⩾j) 前面的元素个数为:
- 第 1 行:1 个元素 ( a 1 , 1 ) (a_{1,1}) (a1,1)。
- 第 2 行:2 个元素 ( a 2 , 1 , a 2 , 2 ) (a_{2,1}, a_{2,2}) (a2,1,a2,2)。
- …
- 第 i − 1 i-1 i−1 行: i − 1 i-1 i−1 个元素 ( a i − 1 , 1 , a i − 1 , 2 , ⋯ , a i − 1 , j − 1 ) (a_{i-1,1}, a_{i-1,2}, \cdots, a_{i-1,j-1}) (ai−1,1,ai−1,2,⋯,ai−1,j−1)。
- 第 i i i 行: j − 1 j-1 j−1 个元素 ( a 1 , 1 , a 1 , 2 , ⋯ , a 1 , j − 1 ) (a_{1,1}, a_{1,2}, \cdots, a_{1,j-1}) (a1,1,a1,2,⋯,a1,j−1)。
因此,元素
a
i
j
a_{ij}
aij 在数组
B
B
B 中的下标
k
=
1
+
2
+
⋯
+
(
i
−
1
)
+
j
−
1
=
i
(
i
−
1
)
/
2
+
j
−
1
k = 1 + 2 + \cdots + (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
,
j
)
k = \left\{ \begin{array}{l} \frac{i(i-1)}{2} + j - 1, \quad i \geqslant j (\text{下三角区和主对角线元素}) \\ \frac{j(j-1)}{2} + i - 1, \quad i < j (\text{上三角区元素} a_{i,j} = a_{j,j}) \end{array} \right.
k={2i(i−1)+j−1,i⩾j(下三角区和主对角线元素)2j(j−1)+i−1,i<j(上三角区元素ai,j=aj,j)
- 当数组下标从 1 开始时,可以采用同样的推导方法,请读者自行思考。
注意事项
二维数组 A [ n ] [ n ] A[n][n] A[n][n] 和 A [ 0... n − 1 ] [ 0... n − 1 ] A[0...n-1][0...n-1] A[0...n−1][0...n−1] 的写法是等价的。若数组写成 A [ 1... n ] [ 1... n ] A[1...n][1...n] A[1...n][1...n],则表示指定了下标是从 1 开始的。二维数组元素写为 a [ i ] [ j ] a[i][j] a[i][j],注意数组元素下标 i i i 和 j j j 通常是从 0 开始的。矩阵元素通常写为 a i , j a_{i,j} ai,j,行号 i i i 和列号 j j j 通常是从 1 开始的。
三角矩阵
定义
三角矩阵是一种特殊的矩阵,其中只有对角线及其一侧的元素可能不为零。根据元素分布的不同,三角矩阵可以分为上三角矩阵和下三角矩阵。
上三角矩阵
上三角矩阵是指矩阵中,下三角区的所有元素均为同一常量。其存储思想与对称矩阵类似,不同之处在于存储完下三角区和主对角线上的元素之后,紧接着存储对角线上方的常量一次,所以可以将 n n n 阶上三角矩阵 A A A 压缩存储在一维数组 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 = \left\{ \begin{array}{l} \frac{(i-1)(2n-i+2)}{2} + (j-i), \quad i \leqslant j (\text{上三角区和主对角线元素}) \\ \frac{n(n+1)}{2}, \quad i > j (\text{下三角区元素}) \end{array} \right. k={2(i−1)(2n−i+2)+(j−i),i⩽j(上三角区和主对角线元素)2n(n+1),i>j(下三角区元素)
下三角矩阵
下三角矩阵是指矩阵中,上三角区的所有元素均为同一常量。其存储思想与对称矩阵类似,不同之处在于存储完下三角区和主对角线上的元素之后,紧接着存储对角线上方的常量一次,所以可以将 n n n 阶下三角矩阵 A A A 压缩存储在一维数组 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 = \left\{ \begin{array}{l} \frac{i(i-1)}{2} + j - 1, \quad i \geqslant j (\text{下三角区和主对角线元素}) \\ \frac{n(n+1)}{2}, \quad i < j (\text{上三角区元素}) \end{array} \right. k={2i(i−1)+j−1,i⩾j(下三角区和主对角线元素)2n(n+1),i<j(上三角区元素)
注意事项
以上推导均假设数组的下标从 0 开始,若题设有具体要求,则应该灵活应对。
三对角矩阵
定义
三对角矩阵也称带状矩阵。对于 n n n 阶矩阵 A A A 中的任意一个元素 a i j a_{ij} aij,当 ∣ i − j ∣ > 1 |i-j| > 1 ∣i−j∣>1 时,若有 a i j = 0 ( 1 ⩽ i , j ⩽ n ) a_{ij} = 0 (1 \leqslant i, j \leqslant n) aij=0(1⩽i,j⩽n),则称为三对角矩阵。在三对角矩阵中,所有非零元素都集中在以主对角线为中心的 3 条对角线的区域,其他区域的元素都为零。
三对角矩阵的压缩存储
三对角矩阵 A A A 也可以采用压缩存储,将 3 条对角线上的元素按行优先方式存放在一维数组 B B B 中,且 a 1 , 1 a_{1,1} a1,1 存放于 B [ 0 ] B[0] B[0] 中。
三对角矩阵的下标对应关系
由此可以计算矩阵 A A A 中 3 条对角线上的元素 a i j ( 1 ⩽ i , j ⩽ n , ∣ i − j ∣ ⩽ 1 ) a_{ij} (1 \leqslant i, j \leqslant n, |i-j| \leqslant 1) aij(1⩽i,j⩽n,∣i−j∣⩽1) 在一维数组 B B B 中存放的下标为 k = 2 i + j − 3 k = 2i + j - 3 k=2i+j−3
反之,若已知三对角矩阵中的某个元素 a i j a_{ij} aij 存放在一维数组 B B B 的第 k k k 个位置,则有 i = ⌊ ( k + 1 ) 3 ⌋ + 1 i = \left\lfloor \frac{(k+1)}{3} \right\rfloor + 1 i=⌊3(k+1)⌋+1,$ j = k − 2 i + 3 j = k - 2i + 3 j=k−2i+3。例如:
- 当 k = 0 k = 0 k=0 时, i = ⌊ ( 0 + 1 ) 3 ⌋ + 1 = 1 i = \left\lfloor \frac{(0 + 1)}{3} \right\rfloor + 1 = 1 i=⌊3(0+1)⌋+1=1, j = 0 − 2 × 1 + 3 = 1 j = 0 - 2 \times 1 + 3 = 1 j=0−2×1+3=1,存放的是 a 1 , 1 a_{1,1} a1,1;
- 当 k = 2 k = 2 k=2 时, i = ⌊ ( 2 + 1 ) 3 ⌋ = 2 i = \left\lfloor \frac{(2 + 1)}{3} \right\rfloor = 2 i=⌊3(2+1)⌋=2, j = 2 − 2 × 2 + 3 = 1 j = 2 - 2 \times 2 + 3 = 1 j=2−2×2+3=1,存放的是 a 2 , 1 a_{2,1} a2,1;
- 当 k = 4 k = 4 k=4 时, i = ⌊ ( 4 + 1 ) 3 ⌋ = 2 i = \left\lfloor \frac{(4 + 1)}{3} \right\rfloor = 2 i=⌊3(4+1)⌋=2, j = 4 − 2 × 2 + 3 = 3 j = 4 - 2 \times 2 + 3 = 3 j=4−2×2+3=3,存放的是 a 2 , 3 a_{2,3} a2,3。
以上推导均假设数组的下标从 0 开始,若题设有具体要求,则应该灵活应对。
4、稀疏矩阵
定义
矩阵中非零元素的个数 t t t,相对矩阵元素的个数 s s s 来说非常少,即 s ≫ t s \gg t s≫t 的矩阵称为稀疏矩阵。例如,一个矩阵的阶为 100 × 100 100 \times 100 100×100,该矩阵中只有少于 100 个非零元素。
存储稀疏矩阵需要保存的信息
若采用常规的方法存储稀疏矩阵,则相当浪费存储空间,因此仅存储非零元素。但通常非零元素的分布没有规律,所以仅存储非零元素的值是不够的,还要存储它所在的行和列。因此,将非零元素及其相应的行和列构成一个三元组(行标 i i i,列标 j j j,值 a i j a_{ij} aij)。然后按照某种规律存储这些三元组线性表。稀疏矩阵压缩存储后便失去了随机存取特性。
适合稀疏矩阵压缩存储的存储结构
稀疏矩阵的三元组表既可以采用数组存储,又可以采用十字链表存储。当存储稀疏矩阵时,不仅要保存三元组表,而且要保存稀疏矩阵的行数、列数和非零元素的个数。
数组存储
数组存储是一种常见的稀疏矩阵存储方式,适用于非零元素分布较为规则的情况。
十字链表法存储
十字链表法存储是一种更为灵活的稀疏矩阵存储方式,适用于非零元素分布不规则的情况。
四、参考资料
鲍鱼科技课件
b站免费王道课后题讲解:
网课全程班: