3.4 数组与特殊矩阵

数组的行优先/列优先地址计算,对称矩阵、三角矩阵、三对角矩阵的压缩存储,以及稀疏矩阵的三元组和十字链表。

考查要求 ★★☆ 理解 行优先与列优先对称矩阵三角矩阵三对角矩阵稀疏矩阵

数组的定义

数组是由 nn(n≥1n \ge 1)个相同类型的数据元素构成的有限序列,每个数据元素称为一个数组元素,每个元素在 nn 个线性关系中的序号称为该元素的下标。

数组是线性表的推广:一维数组可视为一个线性表;二维数组可视为其数据元素是定长线性表的线性表。数组一旦被定义,其维数和维界就不再改变——除了结构的初始化和销毁外,数组只会有存取元素和修改元素的操作。

数组的存储结构

一维数组 A[0..n−1]A[0..n-1] 的存储地址:LOC(ai)=LOC(a0)+i×L\mathrm{LOC}(a_i) = \mathrm{LOC}(a_0) + i \times L(LL 为每个元素所占的存储单元)。

对于多维数组,有两种映射方法:

行优先(C 语言)a00#0a01#1a02#2a10#3a11#4a12#5a20#6a21#7a22#8列优先(Fortran)a00#0a01#3a02#6a10#1a11#4a12#7a20#2a21#5a22#8
#k 表示元素在一维存储空间中的次序(虚线为存储顺序)

对于行下标范围 [0,h1][0, h_1]、列下标范围 [0,h2][0, h_2] 的二维数组:

行优先: LOC(ai,j)=LOC(a0,0)+[ i×(h2+1)+j ]×L\text{行优先:}\ \mathrm{LOC}(a_{i,j}) = \mathrm{LOC}(a_{0,0}) + [\,i \times (h_2 + 1) + j\,] \times L 列优先: LOC(ai,j)=LOC(a0,0)+[ j×(h1+1)+i ]×L\text{列优先:}\ \mathrm{LOC}(a_{i,j}) = \mathrm{LOC}(a_{0,0}) + [\,j \times (h_1 + 1) + i\,] \times L

特殊矩阵的压缩存储

压缩存储:为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间,目的是节省存储空间。

特殊矩阵:具有许多相同矩阵元素或零元素,并且这些元素的分布有一定规律性的矩阵,例如对称矩阵、上(下)三角矩阵、对角矩阵。

压缩存储的关键是找出矩阵元素 ai,ja_{i,j} 与它在一维数组 BB 中下标 kk 的映射关系。点击下方矩阵中的任意元素,观察它被存放到 BB 的哪个位置:

交互演示特殊矩阵的压缩存储(点击矩阵中的元素)
123456123456a11a12a13a14a15a16a21a22a23a24a25a26a31a32a33a34a35a36a41a42a43a44a45a46a51a52a53a54a55a56a61a62a63a64a65a66A[1..6][1..6](绿色为实际存储的元素)一维数组 B[0..20]a110a211a222a313a324a335a416a427a438a449a5110a5211a5312a5413a5514a6115a6216a6317a6418a6519a6620a53 → B[12]k = 5(5−1)/2 + 3 − 1 = 12只存储主对角线及下三角部分,共 n(n+1)/2 个元素
通用公式:i ≥ j 时 k = i(i−1)/2 + j − 1;i < j 时利用 a_ij = a_ji 交换下标(i、j 从 1 开始,B 下标从 0 开始)

对称矩阵

nn 阶方阵中任意元素都满足 ai,j=aj,ia_{i,j} = a_{j,i},只需存放主对角线和下三角区(共 n(n+1)2\frac{n(n+1)}{2} 个元素)。按行优先存放下三角元素 ai,ja_{i,j}(i≥ji \ge j,下标从 1 开始,BB 下标从 0 开始):

  • 第 1 行有 1 个元素,第 2 行有 2 个……第 i−1i-1 行有 i−1i-1 个,所以前 i−1i-1 行共有 i(i−1)2\frac{i(i-1)}{2} 个元素;
  • 在第 ii 行中,ai,ja_{i,j} 前面还有 j−1j-1 个元素。
k={i(i−1)2+j−1,i≥j (下三角区和主对角线)j(j−1)2+i−1,i<j (上三角区,利用 ai,j=aj,i)k = \begin{cases} \dfrac{i(i-1)}{2} + j - 1, & i \ge j \ (\text{下三角区和主对角线}) \\[2mm] \dfrac{j(j-1)}{2} + i - 1, & i < j \ (\text{上三角区,利用 } a_{i,j} = a_{j,i}) \end{cases}

三角矩阵

  • 下三角矩阵:上三角区所有元素均为同一常量 cc。存储完下三角区和主对角线后,紧接着存储一次常量 cc,BB 共 n(n+1)2+1\frac{n(n+1)}{2} + 1 个单元。
  • 上三角矩阵:下三角区所有元素均为同一常量。按行优先存储上三角元素 ai,ja_{i,j}(i≤ji \le j)时,第 1 行有 nn 个元素,第 2 行有 n−1n-1 个……第 i−1i-1 行有 n−i+2n-i+2 个,因此
k=(i−1)(2n−i+2)2+(j−i),i≤jk = \frac{(i-1)(2n-i+2)}{2} + (j - i), \quad i \le j

三对角矩阵

对角矩阵也称带状矩阵。三对角矩阵中所有非零元素都集中在以主对角线为中心的 3 条对角线区域,即 ∣i−j∣>1|i - j| > 1 时 ai,j=0a_{i,j} = 0。

按行优先存储时,第 1 行有 2 个元素,其余每行 3 个元素(最后一行 2 个),共 3n−23n-2 个。ai,ja_{i,j} 前面有 3(i−1)−13(i-1)-1 个元素,再加上本行中它前面的 j−i+1j-i+1 个元素:

k=3(i−1)−1+(j−i+1)=2i+j−3k = 3(i-1) - 1 + (j - i + 1) = 2i + j - 3

反过来,已知 kk 求 i,ji, j:i=⌊k+13+1⌋i = \left\lfloor \dfrac{k+1}{3} + 1 \right\rfloor,j=k−2i+3j = k - 2i + 3。

稀疏矩阵

矩阵中非零元素的个数 tt 相对矩阵元素的个数 ss 来说非常少,即 s≫ts \gg t 的矩阵称为稀疏矩阵。例如一个 100×100100 \times 100 的矩阵中只有不到 100 个非零元素。

稀疏矩阵的非零元素分布没有规律,因此除了存放元素值,还要存储它所在的行和列,构成三元组(行标 ii,列标 jj,值 ai,ja_{i,j})。

0123012340000060090002300
稀疏矩阵 M
ij值0041262193123
对应的三元组表
  • 三元组表(顺序存储)压缩后失去了随机存取特性。
  • 稀疏矩阵也可以采用十字链表存储:每个非零元素用一个结点表示,结点包含行号、列号、值,以及指向同行下一个非零元素的右指针和指向同列下一个非零元素的下指针。

即时练习

即时练习5 题
点击选项即可作答
  1. 1
    适用于压缩存储稀疏矩阵的两种存储结构是( )。
  2. 2
    有一个 n×n 的对称矩阵 A,将其下三角部分按行存放在一维数组 B 中,而 A[0][0] 存放于 B[0] 中,则第 i 行的对角元素 A[i][i] 存放于 B 中的( )处。
  3. 3
    设有一个 10 阶的对称矩阵 A,采用压缩存储方式,以行序为主存储,a₁,₁ 为第一个元素,其存储地址为 1,每个元素占一个地址空间,则 a₈,₅ 的地址为( )。
  4. 4
    二维数组 A 按行优先方式存储,每个元素占用 1 个存储单元。若元素 A[0][0] 的存储地址是 100,A[3][3] 的存储地址是 220,则元素 A[5][5] 的存储地址是( )。
  5. 5
    将三对角矩阵 A[1..100][1..100] 按行优先存入一维数组 B[1..298] 中,A 中元素 A₆₆,₆₅ 在数组 B 中的位置 k 为( )。
学完了吗?

标记完成后,侧栏会显示进度。进度仅保存在本浏览器中。