-
三对角矩阵
- 是一种特殊的n×n矩阵,其中非零元素仅出现在主对角线及其上下两条相邻的对角线上。
- 总共最多有 $ 3n - 2 $ 个非零元素(当 $ n \geq 2 $),因此可以压缩存储到一维数组中以节省空间。
- 存储方式:按行优先顺序将非零元素存入一维数组。对于元素 $ a_{ij} $(下标从1开始),其在一维数组中的位置为:
k=2i+j−3(若使用0起始下标) k = 2i + j - 3 \quad \text{(若使用0起始下标)} k=2i+j−3(若使用0起始下标)
或者如题所述(使用1起始下标和公式 $ k=2i+j−2 $)对应的是从1开始的一维数组索引。示例:$ a_{2,2} $ 在主对角线上,代入得 $ k = 2×2 + 2 − 2 = 4 $,即第四个存储单元。
-
稀疏矩阵
- 定义:在一个较大的矩阵中,非零元素个数远少于零元素(例如小于5%),且分布无规律。
- 直接用二维数组存储会造成大量空间浪费,故采用压缩存储。
- 常见存储结构:
- 三元组顺序表:每个非零元素用 (i, j, aij) 表示,存储在顺序结构(如数组)中,适合转置、加法等操作。
- 十字链表(Orthogonal List):链式存储结构,每个节点包含行、列、值、指向同行下一个元素的指针、指向同列下一个元素的指针。适合频繁修改的稀疏矩阵。
-
广义表(Generalized List)
- 定义:是线性表的推广,形式为 $ LS = (\alpha_1, \alpha_2, …, \alpha_n) $,其中每个 $ \alpha_i $ 可以是单个原子(不可再分的数据元素),也可以是一个广义表(即可嵌套)。
- 特点:
- 有层次结构,支持递归定义。
- 长度:最外层元素的个数。
- 深度:括号的最大嵌套层数。
- 示例:
$ A = (a, b) $:长度为2,深度为1
$ B = (a, (b, c), d) $:长度为3,深度为2
$ C = (A, B) $:长度为2,深度为3(因嵌套A、B) - 与线性表的区别:
对比项 线性表 广义表 元素类型 原子(不可再分) 原子或子表(可嵌套) 结构 平坦结构 层次/树状/递归结构 应用场景 一般序列数据 符号处理、Lisp语言基础、表达式树
这些知识点属于“数组与广义表”章节的核心内容,主要用于高效组织和处理具有特殊结构的数据,在编译器设计、科学计算(如稀疏方程求解)、人工智能等领域有广泛应用。
在三对角矩阵中,非零元素仅分布在主对角线及其上下两条相邻的对角线上。为了节省存储空间,通常采用压缩存储的方式,将这些非零元素按行优先顺序存入一维数组中。
我们来推导元素 $ a_{ij} $(下标从1开始)在一维数组中的存储位置公式:
k=2i+j−3(若数组下标从0开始)
k = 2i + j - 3 \quad \text{(若数组下标从0开始)}
k=2i+j−3(若数组下标从0开始)
或
k=2i+j−2(若数组下标从1开始)
k = 2i + j - 2 \quad \text{(若数组下标从1开始)}
k=2i+j−2(若数组下标从1开始)
✅ 推导过程:
考虑一个 $ n \times n $ 的三对角矩阵,其每行最多有3个非零元素,但首行和末行例外:
- 第1行:只有 $ a_{11}, a_{12} $ → 2个非零元
- 第2行到第$ n-1 $行:各有3个非零元
- 第$ n $行:只有 $ a_{n,n-1}, a_{nn} $ → 2个非零元
但我们按“每行最多贡献3个元素”的思路进行累计,并根据实际列位置确定偏移。
步骤1:统计前 $ i-1 $ 行共占多少个非零元素
观察规律:
- 第1行最多有2个非零元(列1~2)
- 第2行到第$ i-1 $行(如果 $ i > 2 $),每行最多有3个非零元
但实际上,在压缩存储中,我们统一按“前 $ i-1 $ 行共占据 $ 2(i-1) $”个位置估算?不准确!
更合理的做法是:逐行分析每个位置是否有效,并计算当前元素前面有多少个非零元素。
更好的方式是直接枚举前 $ i-1 $ 行中非零元素的总数。
由于每行最多3个非零元,但第一行少一个,最后一行也少一个,但在整体压缩时,我们仍可以发现一个简洁规律:
每一行 $ r $ 中,非零元素出现在列 $ j = r-1, r, r+1 $ 上(边界除外)
因此,对于第 $ i $ 行中的元素 $ a_{ij} $,我们要计算它前面所有行中已经存储的非零元素个数,再加上它在本行的位置偏移。
关键观察:每一行最多有3个非零元,但从第1行开始:
- 第1行:2个非零元(位置:(1,1), (1,2))
- 第2行:3个非零元((2,1), (2,2), (2,3))
- …
- 第 $ i-1 $ 行:3个非零元(当 $ i \geq 3 $)
所以前 $ i-1 $ 行共有:
countprev=2+3(i−2)=3i−4(当 i≥2)
\text{count}_{\text{prev}} = 2 + 3(i - 2) = 3i - 4 \quad \text{(当 } i \geq 2 \text{)}
countprev=2+3(i−2)=3i−4(当 i≥2)
但这与标准公式不符,说明这种分段处理复杂。
换一种方法 —— 通过具体例子归纳规律。
📌 方法:实例法 + 归纳法
设矩阵为 $ 5 \times 5 $,列出所有非零元素的行列号及其在一维数组中的顺序(从1开始编号):
| 序号 k | i | j | 元素 |
|---|---|---|---|
| 1 | 1 | 1 | a₁₁ |
| 2 | 1 | 2 | a₁₂ |
| 3 | 2 | 1 | a₂₁ |
| 4 | 2 | 2 | a₂₂ |
| 5 | 2 | 3 | a₂₃ |
| 6 | 3 | 2 | a₃₂ |
| 7 | 3 | 3 | a₃₃ |
| 8 | 3 | 4 | a₃₄ |
| 9 | 4 | 3 | a₄₃ |
| 10 | 4 | 4 | a₄₄ |
| 11 | 4 | 5 | a₄₅ |
| 12 | 5 | 4 | a₅₄ |
| 13 | 5 | 5 | a₅₅ |
现在尝试找出 $ k $ 与 $ i,j $ 的关系。
观察第 $ i $ 行第一个非零元素的位置:
- 第1行起始k=1
- 第2行起始k=3
- 第3行起始k=6
- 第4行起始k=9
- 第5行起始k=12
可见:第 $ i $ 行的起始位置为:
starti=3i−3?⇒i=1:0❌
\text{start}_i = 3i - 3 \quad ? \Rightarrow i=1: 0 ❌
starti=3i−3?⇒i=1:0❌
不对。试试:
- $ i=1 $: 起始k=1
- $ i=2 $: 起始k=3 → 前面1行共2个 → $ 2 $
- $ i=3 $: 起始k=6 → 前面2行共 $ 2+3=5 $? 不对,应该是前两行总共5个元素?
重新统计前 $ i-1 $ 行的非零元素总数:
| i | 前 i-1 行元素总数 |
|---|---|
| 1 | 0 |
| 2 | 2(第1行) |
| 3 | 2+3=5 |
| 4 | 2+3+3=8 |
| 5 | 2+3+3+3=11 |
所以第 $ i $ 行的第一个元素对应的 $ k = \text{prev_total} + 1 $
而第 $ i $ 行中,非零元素位于列 $ j = i-1, i, i+1 $,即:
- 列 $ i-1 $:第一个元素 → 偏移0
- 列 $ i $:第二个 → 偏移1
- 列 $ i+1 $:第三个 → 偏移2
但由于第1行没有 $ j=0 $,所以只保留存在的元素。
于是,在第 $ i $ 行中,列索引 $ j $ 对应的行内偏移量为:
offset_in_row={j−(i−1)if j≥i−1undefinedotherwise⇒即 j−i+1
\text{offset\_in\_row} =
\begin{cases}
j - (i - 1) & \text{if } j \geq i - 1 \\
\text{undefined} & \text{otherwise}
\end{cases}
\Rightarrow \text{即 } j - i + 1
offset_in_row={j−(i−1)undefinedif j≥i−1otherwise⇒即 j−i+1
但由于列从 $ i-1 $ 开始,所以该行第一个元素是 $ j=i-1 $,对应偏移0;
因此:列 $ j $ 在该行中的位置为:$ j - (i - 1) = j - i + 1 $
但是注意:这个值只能是 0、1 或 2(因为最多三个元素)
那么总的前面元素个数为:
k=(前 i−1 行元素总数)+(j−i+1)
k = (\text{前 } i-1 \text{ 行元素总数}) + (j - i + 1)
k=(前 i−1 行元素总数)+(j−i+1)
前 $ i-1 $ 行元素总数:
- 当 $ i = 1 $: 0
- 当 $ i \geq 2 $: $ 2 + 3(i - 2) = 3i - 4 $? 验证:
- $ i=2 $: $ 3×2−4=2 $ ✅
- $ i=3 $: $ 5 $ ✅
- $ i=4 $: $ 8 $ ✅
- $ i=5 $: $ 11 $ ✅
所以:
前 i−1 行元素总数={0,i=13i−4,i≥2
\text{前 } i-1 \text{ 行元素总数} =
\begin{cases}
0, & i = 1 \\
3i - 4, & i \geq 2
\end{cases}
前 i−1 行元素总数={0,3i−4,i=1i≥2
但这不是一个统一表达式。
有没有更简洁的方法?
🔍 发现统一规律(关键技巧):
观察上面表格中每一个 $ a_{ij} $ 的 $ k $ 值:
尝试代入公式:
k=2i+j−2
k = 2i + j - 2
k=2i+j−2
验证几个点:
- $ i=1,j=1 $: $ 2×1 + 1 − 2 = 1 $ ✅
- $ i=1,j=2 $: $ 2 + 2 − 2 = 2 $ ✅
- $ i=2,j=1 $: $ 4 + 1 − 2 = 3 $ ✅
- $ i=2,j=2 $: $ 4 + 2 − 2 = 4 $ ✅
- $ i=2,j=3 $: $ 4 + 3 − 2 = 5 $ ✅
- $ i=3,j=2 $: $ 6 + 2 − 2 = 6 $ ✅
- $ i=3,j=3 $: $ 6 + 3 − 2 = 7 $ ✅
- $ i=3,j=4 $: $ 6 + 4 − 2 = 8 $ ✅
- $ i=4,j=3 $: $ 8 + 3 − 2 = 9 $ ✅
- $ i=4,j=4 $: $ 8 + 4 − 2 = 10 $ ✅
- $ i=4,j=5 $: $ 8 + 5 − 2 = 11 $ ✅
- $ i=5,j=4 $: $ 10 + 4 − 2 = 12 $ ✅
- $ i=5,j=5 $: $ 10 + 5 − 2 = 13 $ ✅
全部匹配!✅
所以结论成立:
在以行序为主序存储三对角矩阵时,若使用 从1开始的下标,则元素 $ a_{ij} $ 对应的一维数组下标为:
k=2i+j−2 k = 2i + j - 2 k=2i+j−2
✅ 公式推导总结:
为什么是 $ 2i + j - 2 $?
我们可以这样理解:
- 每一行 $ i $ 最多有3个非零元素,但第1行和第n行只有2个。
- 然而,如果我们假设每一行都“贡献了两个完整元素”,然后加上列偏移,就能得到统一公式。
- 实际上,这是通过对存储模式的归纳得出的经验公式。
- 更本质地看:前 $ i-1 $ 行大约贡献了 $ 2(i-1) $ 个元素(因为平均每行约2个),再加上当前行中第 $ j $ 所处的位置偏移。
但精确地说,该公式来源于对三对角结构中每行非零元素分布的系统编号。
另一种解释:
- 主对角线上的元素 $ a_{ii} $ 所在位置为 $ k = 2i + i - 2 = 3i - 2 $?不对,应为 $ k = 2i + i - 2 = 3i - 2 $,但前面已知 $ a_{33} $ 是第7个 → $ 3×3−2=7 $ ✅
其实也可以反向验证各种对角线上的位置都符合。
✅ 总结
| 内容 | 说明 |
|---|---|
| 公式 | $ k = 2i + j - 2 $(下标从1开始) |
| 使用条件 | 三对角矩阵,按行优先压缩存储 |
| 下标范围 | $ 1 \leq i,j \leq n $,且 $ |
| 若数组从0开始 | 则 $ k = 2i + j - 3 $ |


818

被折叠的 条评论
为什么被折叠?



