目录
一、对称矩阵1. 压缩存储所需的空间大小2. 矩阵元素行号 i、列号 j 与数组元素下标 k 之间的关系3. 其他情况1)矩阵下标从 1 开始、数组下标从 1 开始2)矩阵下标从 0 开始、数组下标从 0 开始3)矩阵下标从 0 开始、数组下标从 1 开始
4. 例题
二、三角矩阵1. 压缩存储所需的空间大小2. 矩阵元素行号 i、列号 j 与数组元素下标 k 之间的关系3. 其他情况1)矩阵下标从 1 开始、数组下标从 1 开始2)矩阵下标从 0 开始、数组下标从 0 开始3)矩阵下标从 0 开始、数组下标从 1 开始
4. 上三角矩阵采用行优先存储的应用1)矩阵下标从 1 开始、数组下标从 1 开始2)矩阵下标从 0 开始、数组下标从 0 开始3)矩阵下标从 0 开始、数组下标从 1 开始
5. 例题
三、三对角矩阵1. 压缩存储所需的空间大小2. 矩阵元素行号i、列号j与数组元素下标k之间的关系3. 其他情况1)矩阵下标从 1 开始、数组下标从 1 开始2)矩阵下标从 0 开始、数组下标从 0 开始3)矩阵下标从 0 开始、数组下标从 1 开始
4. 例题
特殊矩阵指的是具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的分布具有一定规律性的矩阵(例如:对称矩阵、上或下三角矩阵、对角矩阵等);而压缩存储指的是将多个值相同的元素只分配给一个存储空间,而对零元素不分配空间。因此特殊矩阵的压缩存储方法是找出特殊矩阵中值相同的矩阵元素的分布规律,并把那些呈现规律性分布的、值相同的多个矩阵元素压缩存储到一个存储空间中。
一、对称矩阵
若对一个 n 阶矩阵 A 中的任意一个元素 ai,j 都有 ai,j = aj,i(1 ≤ i, j ≤ n),则称其为对称矩阵。其中的元素可以划分为三个部分,即上三角区、主对角线和下三角区。
[
a
1
,
1
a
1
,
2
⋯
a
1
,
n
a
2
,
1
a
2
,
2
⋯
a
2
,
n
⋮
⋮
⋱
⋮
a
n
,
1
a
n
,
2
⋯
a
n
,
n
]
\left[ \begin{matrix} a_{1,1} & a_{1,2} & \cdots & a_{1,n}\\ a_{2,1} & a_{2,2} & \cdots & a_{2,n}\\ \vdots & \vdots & \ddots & \vdots\\ a_{n,1} & a_{n,2} & \cdots & a_{n,n} \end{matrix} \right]
a1,1a2,1⋮an,1a1,2a2,2⋮an,2⋯⋯⋱⋯a1,na2,n⋮an,n
其中 i < j 是上三角区,i = j 是主对角线,i > j 是下三角区。
1. 压缩存储所需的空间大小
对于 n 阶对称矩阵,上三角区的所有元素和下三角区的对应元素相同,若将所有元素都存放起来的话,会浪费几乎一半的空间,为此可以只存放对称矩阵的上或下三角部分(含主对角)的元素。
以存放下三角部分为例,如果要将 n 阶对称矩阵 A 存放在一维数组 B 中,那么 B 所需的空间大小为 n·(n+1)/2(即 1+2+……+n ,等差数列求和),元素 ai,j 存放在 b[k] 中。
2. 矩阵元素行号 i、列号 j 与数组元素下标 k 之间的关系
矩阵元素 ai,j 的行号 i 和列号 j 通常是从 1 开始的,而数组元素 b[k] 的下标 k 通常是从 0 开始的。在计算 i , j 与 k 之间的对应关系时,假设只存放下三角区部分(含对角线,即 i ≥ j 的部分):
在数组 B 中,位于元素 ai,j(i ≥ j)前面的元素个数为:
第 1 行:1个元素(a1,1)
第 2 行:2个元素(a2,1 , a2,2) ……
第 i-1 行:i-1 个元素(ai-1,1 , ai-1,2 , …… , ai-1,i-1) 【前面 i-1 行满足 i ≥ j 的元素都要存储在 B 中】
第 i 行:j-1 个元素(ai,1,ai,2,……,ai,j-1)
因此,元素 ai,j(i ≥ j)在数组 B 中的下标 k = [1+2+……+(i-1)] + (j-1) = i·(i-1)/2 + j - 1;而上三角区部分(即 i < j 的部分)i、j 与 k 之间的关系就更好推导了,由于对称矩阵的元素满足 ai,j = aj,i ,所以 ai,j 与 aj,i 在 B 上对应的存储空间是同一个,因此将 i 与 j 进行调换即可,即 k = j·(j-1)/2 + i - 1。
矩阵下标从 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\ge j(下三角区和主对角线元素)\\ \frac{j(j-1)}{2}+i-1,\quad i < j(上三角区元素 a_{ij}=a_{ji})\\ \end{cases}
k={2i(i−1)+j−1,i≥j(下三角区和主对角线元素)2j(j−1)+i−1,i 3. 其他情况 ① 二维数组 A[n][n] 和 A[0…n-1][0…n-1] 的写法是等价的,若二维数组元素写为 A[i][j] ,则数组元素下标的 i 和 j 通常是从 0 开始的; ② 若数组写为 A[1…n][1…n] ,则说明指定了从下标 1 开始存储元素; ③ 矩阵元素通常写为 ai,j 或 a(i)(j) ,这里的行号 i 与列号 j 是从 1 开始的。 我们在上述讨论了矩阵下标从 1 开始、数组下标从 0 开始的情况,下面讨论一下矩阵下标从 0 开始或数组下标从 1 开始的情况(都以存放含对角线的下三角区部分为例)。 1)矩阵下标从 1 开始、数组下标从 1 开始 k = { i ( i − 1 ) 2 + j , i ≥ j ( 下三角区和主对角线元素 ) j ( j − 1 ) 2 + i , i < j ( 上三角区元素 a i j = a j i ) k= \begin{cases} \frac{i(i-1)}{2}+j,\quad i\ge j(下三角区和主对角线元素)\\ \frac{j(j-1)}{2}+i,\quad i < j(上三角区元素 a_{ij}=a_{ji})\\ \end{cases} k={2i(i−1)+j,i≥j(下三角区和主对角线元素)2j(j−1)+i,i 2)矩阵下标从 0 开始、数组下标从 0 开始 k = { i ( i + 1 ) 2 + j , i ≥ j ( 下三角区和主对角线元素 ) j ( j + 1 ) 2 + i , i < j ( 上三角区元素 a i j = a j i ) k= \begin{cases} \frac{i(i+1)}{2}+j,\quad i\ge j(下三角区和主对角线元素)\\ \frac{j(j+1)}{2}+i,\quad i < j(上三角区元素 a_{ij}=a_{ji})\\ \end{cases} k={2i(i+1)+j,i≥j(下三角区和主对角线元素)2j(j+1)+i,i 3)矩阵下标从 0 开始、数组下标从 1 开始 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\ge j(下三角区和主对角线元素)\\ \frac{j(j+1)}{2}+i+1,\quad i < j(上三角区元素 a_{ij}=a_{ji})\\ \end{cases} k={2i(i+1)+j+1,i≥j(下三角区和主对角线元素)2j(j+1)+i+1,i 4. 例题 ① 有一个 n × n 的对称矩阵 A , 将其下三角部分按行存放在一维数组 B 中,而 A[0][0] 存放于 B[0] 中,则笫 i + 1 行的对角元素 A[i][i] 存放于 B 中的()处。 A. (i + 3) × i / 2 B. (i + 1) × i / 2 C. (2n - i + 1) × i / 2 D. (2n - i - 1) × i / 2 A(矩阵下标从0开始、数组下标从0开始) ② 【2018 统考真题】设有一个 12 × 12 阶对称矩阵 M,将其上三角部分的元素 mi,j(1 ≤ i ≤ j ≤ 12)按行优先存入 C 语言的一维数组 N 中,元素 m6,6 在 N 中的下标是()。 A. 50 B. 51 C. 55 D. 66 A(上三角按行优先=下三角按列优先,矩阵下标从1开始、数组下标从0开始) ③ 【2020 统考真题】将一个 10 × 10 阶对称矩阵 M 的上三角部分的元素 mi,j(1 ≤ i ≤ j ≤ 10)按列优先存入 C 语言的一维数组 N 中,元素 m7,2 在 N 中的下标是()。 A. 15 B. 16 C. 22 D. 23 C(上三角按列优先=下三角按行优先,矩阵下标从1开始、数组下标从0开始) 二、三角矩阵 下三角矩阵中,上三角区的所有元素均为同一常量;上三角矩阵中,下三角区的所有元素均为同一常量。 (a) 下三角矩阵 [ a 1 , 1 a 2 , 1 a 2 , 2 ⋮ ⋮ ⋱ a n , 1 a n , 2 ⋯ a n , n ] \left[ \begin{matrix} a_{1,1} & & & \\ a_{2,1} & a_{2,2} & & \\ \vdots & \vdots & \ddots & \\ a_{n,1} & a_{n,2} & \cdots & a_{n,n} \end{matrix} \right] a1,1a2,1⋮an,1a2,2⋮an,2⋱⋯an,n (b) 上三角矩阵 [ a 1 , 1 a 1 , 2 ⋯ a 1 , n a 2 , 2 ⋯ a 2 , n ⋱ ⋮ a n , n ] \left[ \begin{matrix} a_{1,1} & a_{1,2} & \cdots & a_{1,n}\\ & a_{2,2} & \cdots & a_{2,n}\\ & & \ddots & \vdots\\ & & & a_{n,n} \end{matrix} \right] a1,1a1,2a2,2⋯⋯⋱a1,na2,n⋮an,n 1. 压缩存储所需的空间大小 其存储思想与对称矩阵相似,不同之处在于存储完下三角区和主对角线上的元素之后,紧接着存储对角线上方的常量一次。 因此,如果要将 n 阶下三角矩阵 A 存放在一维数组 B 中,那么 B 所需的空间大小为 n(n+1)/2+1 。 2. 矩阵元素行号 i、列号 j 与数组元素下标 k 之间的关系 以存储下三角区部分(含对角线,即 i ≥ j 的部分)为例,矩阵下标从 1 开始、数组下标从 0 开始: 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\ge j(下三角区和主对角线元素)\\ \frac{n(n+1)}{2},\quad i < j(上三角区元素)\\ \end{cases} k={2i(i−1)+j−1,i≥j(下三角区和主对角线元素)2n(n+1),i 3. 其他情况 1)矩阵下标从 1 开始、数组下标从 1 开始 k = { i ( i − 1 ) 2 + j , i ≥ j ( 下三角区和主对角线元素 ) n ( n + 1 ) 2 + 1 , i < j ( 上三角区元素 ) k= \begin{cases} \frac{i(i-1)}{2}+j,\quad i\ge j(下三角区和主对角线元素)\\ \frac{n(n+1)}{2}+1,\quad i < j(上三角区元素)\\ \end{cases} k={2i(i−1)+j,i≥j(下三角区和主对角线元素)2n(n+1)+1,i 2)矩阵下标从 0 开始、数组下标从 0 开始 k = { i ( i + 1 ) 2 + j , i ≥ j ( 下三角区和主对角线元素 ) n ( n + 1 ) 2 , i < j ( 上三角区元素 ) k= \begin{cases} \frac{i(i+1)}{2}+j,\quad i\ge j(下三角区和主对角线元素)\\ \frac{n(n+1)}{2},\quad i < j(上三角区元素)\\ \end{cases} k={2i(i+1)+j,i≥j(下三角区和主对角线元素)2n(n+1),i 3)矩阵下标从 0 开始、数组下标从 1 开始 k = { i ( i + 1 ) 2 + j + 1 , i ≥ j ( 下三角区和主对角线元素 ) n ( n + 1 ) 2 + 1 , i < j ( 上三角区元素 ) k= \begin{cases} \frac{i(i+1)}{2}+j+1,\quad i\ge j(下三角区和主对角线元素)\\ \frac{n(n+1)}{2}+1,\quad i < j(上三角区元素)\\ \end{cases} k={2i(i+1)+j+1,i≥j(下三角区和主对角线元素)2n(n+1)+1,i 4. 上三角矩阵采用行优先存储的应用 上三角矩阵采用行优先存储等价于下三角矩阵采用列优先存储。 在数组 B 中,位于元素 ai,j(i ≤ j)前面的元素个数为: 第 1 行:n 个元素(a1,1,a1,2,……,a1,n)第 2 行:n-1 个元素(a2,2,……,a2,n) ……第 i-1 行:n-i+2 个元素(ai-1,i-1,……,ai-1,n) 【前面 i-1 行满足 i ≤ j 的元素都要存储在 B 中】第 i 行:j-1 个元素(ai,i,……,ai,j-1) 因此,元素 ai,j(i ≤ j)在数组 B 中的下标 k = [n+(n-1)+……+(n-i+2)] + (j-i+1) - 1 = (i-1)·(2n-i+2)/2 + (j-i)。 矩阵下标从 1 开始、数组下标从 0 开始: 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\le 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(下三角区元素) 1)矩阵下标从 1 开始、数组下标从 1 开始 k = { ( i − 1 ) ( 2 n − i + 2 ) 2 + j − i + 1 , i ≤ j ( 上三角区和主对角线元素 ) n ( n + 1 ) 2 + 1 , i > j ( 下三角区元素 ) k= \begin{cases} \frac{(i-1)(2n-i+2)}{2}+j-i+1,\quad i\le j(上三角区和主对角线元素)\\ \frac{n(n+1)}{2}+1,\quad i > j(下三角区元素)\\ \end{cases} k={2(i−1)(2n−i+2)+j−i+1,i≤j(上三角区和主对角线元素)2n(n+1)+1,i>j(下三角区元素) 2)矩阵下标从 0 开始、数组下标从 0 开始 k = { i ( 2 n − i + 1 ) 2 + j − i + 1 , i ≤ j ( 上三角区和主对角线元素 ) n ( n + 1 ) 2 , i > j ( 下三角区元素 ) k= \begin{cases} \frac{i(2n-i+1)}{2}+j-i+1,\quad i\le j(上三角区和主对角线元素)\\ \frac{n(n+1)}{2},\quad i > j(下三角区元素)\\ \end{cases} k={2i(2n−i+1)+j−i+1,i≤j(上三角区和主对角线元素)2n(n+1),i>j(下三角区元素) 3)矩阵下标从 0 开始、数组下标从 1 开始 k = { i ( 2 n − i + 1 ) 2 + j − i + 2 , i ≤ j ( 上三角区和主对角线元素 ) n ( n + 1 ) 2 + 1 , i > j ( 下三角区元素 ) k= \begin{cases} \frac{i(2n-i+1)}{2}+j-i+2,\quad i\le j(上三角区和主对角线元素)\\ \frac{n(n+1)}{2}+1,\quad i > j(下三角区元素)\\ \end{cases} k={2i(2n−i+1)+j−i+2,i≤j(上三角区和主对角线元素)2n(n+1)+1,i>j(下三角区元素) 5. 例题 ① 若将 n 阶上三角矩阵 A 按列优先顺序压缩存放在一维数组 B[1…n × (n + 1) / 2 + 1] 中,则存放到 B[k] 中的非零元素 ai,j(1 ≤ i, j ≤ n)的下标 i、j 与 k 的对应关系是( )。 A. i × (i + 1) / 2 + j B. i × (i - 1) / 2 + j - 1 C. j × (j - 1) / 2 + i D. j × (j - 1) / 2 + i - 1 C(上三角按列优先=下三角按行优先,矩阵下标从1开始、数组下标从1开始) ② 若将 n 阶下三角矩阵 A 按列优先顺序压缩存放在一维数组 B[1…n·(n + 1)/2+1] 中,则存放到 B[k] 中的非零元素 ai,j(1 ≤ i, j ≤ n)的下标 i、j 与 k 的对应关系是( )。 A. (j - 1) × (2 × n - j + 1) / 2 + i - j B. (j - 1) × (2 × n - j + 2) / 2 + i - j + 1 C. (j - 1) × (2 × n - j + 2) / 2 + i - j D. (j - 1) × (2 × n - j + 1) / 2 + i - j - 1 B(下三角按列优先=上三角按行优先,矩阵下标从1开始、数组下标从1开始) 三、三对角矩阵 对角矩阵也称带状矩阵,对 n 阶矩阵 A 中的任意一个元素 ai,j ,当 |i-j| > 1 时,若有 ai,j = 0(1 ≤ i, j ≤ n),则称为三对角矩阵。在三对角矩阵中,所有非零元素都集中在以对角线为中心的三条对角线的区域,其他区域的元素都为零。 [ 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 ] \left[ \begin{matrix} a_{1,1} & a_{1,2} & & & & \\ a_{2,1} & a_{2,2} & a_{2,3} & & & \\ & a_{3,2} & 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{matrix} \right] a1,1a2,1a1,2a2,2a3,2a2,3a3,3⋱a3,4⋱an−1,n−2⋱an−1,n−1an,n−1an−1,nan,n 1. 压缩存储所需的空间大小 如果要将 n 阶三对角矩阵 A 存放在一维数组 B 中,那么 B 所需的空间大小为 4+3·(n-2) 。 2. 矩阵元素行号i、列号j与数组元素下标k之间的关系 可以计算出矩阵 A 中三条对角线上的元素 ai,j(1 ≤ i, j ≤ n,|i-j| ≤ 1)在一维数组 B 中存放的下标为 k = 2·i+j-3(矩阵下标从 1 开始、数组下标从 0 开始)。 元素 ai,j 的前 i-1 行中,除第 1 行只有两个元素外,其他的 i-2 行都有三个元素;第 i 行的三个元素的下标分别可以通过 2+(j-i) 来计算(j-i 只有 -1、0、1 三种情况,而元素存储的下标分别需要增加 1、2、3);又因为矩阵下标是从 1 开始,而数组下标是从 0 开始,因此从矩阵下标转换为数组下标时还要 -1 。可以推出矩阵元素行号 i、列号 j 与数组元素下标 k 之间的关系为:2+3·(i-2)+2+(j-i)-1 = 2i+j-3。 若已知三对角矩阵中的某个元素 ai,j 存放在一维数组 B 的第 k 个位置,则有 i = ⌊(k+1)/3+1⌋ ,j = k-2i+3 。 由于数组下标是从 0 开始的,因此数组下标为 k 的元素是矩阵中的第 k+1 个非零元素,矩阵除了首尾外的每行都有三个非零元素,且矩阵的行号 i 是从 1 开始,所以 (k+1)/3+1 再向下取整就可以得到存放在数组 B 第 k 个位置的元素所在三对角矩阵中的行号 i ,根据 k = 2i+j-3 ,可以进一步的推出列号 j 。 3. 其他情况 1)矩阵下标从 1 开始、数组下标从 1 开始 k = 2i+j-2 ,若已知三对角矩阵中的某个元素 ai,j 存放在一维数组B的第k个位置,则有 i = ⌊k/3+1⌋ ,j = k-2i+2 。 2)矩阵下标从 0 开始、数组下标从 0 开始 k = 2i+j+1 ,若已知三对角矩阵中的某个元素 ai,j 存放在一维数组 B 的第 k 个位置,则有 i = ⌊k/3+1⌋ ,j = k-2i-1 。 3)矩阵下标从 0 开始、数组下标从 1 开始 k = 2i+j+2,若已知三对角矩阵中的某个元素 ai,j 存放在一维数组 B 的第 k 个位置,则有 i = ⌊(k-1)/3+1⌋ ,j = k-2i-2 。 4. 例题 ① 将三对角矩阵 A[1…100][1…100] 按行优先存入一维数组 B[1…298] 中,数组 A 中元素 A[66][65] 在数组 B 中的位置 k 为( B )。 A. 198 B. 195 C. 197 D. 196 ② 【2016 统考真题】有一个 100 阶的三对角矩阵 M ,其元素 mi,j(1 ≤ i, j ≤ 100)按行优先依次压缩存入下标从 0 开始的一维数组 N 中。元素 m30,30 在 N 中的下标是( B )。 A. 86 B. 87 C. 88 D. 89 不要死记硬背公式,弄清公式的原理后学会自己推导,从而可以在做题时融会贯通、举一反三。