github中有详尽代码可作参考
返回目录
数组的存储结构
- 一维数组
设一维数组为 a[0,⋯,n−1](即有 n个元素,下标从 0到 n−1),类型为 ElemType(长度为 L), ai的存放地址为 LOC(ai)=LOC(a0)+L×i ,此处 0≤i≤n−1;
如果询问是第 j个元素(从 1到 n,注意和下标的差别,与下标相差 1),此时第 j个元素的存放地址为 LOC(aj−1)=LOC(a0)+L×(j−1),此处 1≤j≤n
- 二维数组
行优先(内存地址中一行一行的放,平常使用较多)
设二维数组为 b[0,⋯,n−1][0,⋯,m−1](即有 n×m个元素,行下标从 0到 n−1,列下标从 0到 m−1),类型为 ElemType(长度为 L), ai,j的存放地址为 LOC(ai,j)=LOC(a0,0)+(i×m+j)×L,偏移量是 i×m+j(说明前面有 i行,每行有 m个,当前行的第 j个)
![]()
列优先(内存地址中一列一列的放)
设二维数组为 b[0,⋯,n−1][0,⋯,m−1](即有 n×m个元素,行下标从 0到 n−1,列下标从 0到 m−1),类型为 ElemType(长度为 L), ai,j的存放地址为 LOC(ai,j)=LOC(a0,0)+(j×n+i)×L,偏移量是 j×n+i(说明前面有 j列,每列有 n个,当前列的第 i个)
![]()
计算公式: LOC(ai,j)=LOC(第一个元素)+(ai,j前面的元素个数)∗每个元素所占用字节
特殊矩阵的压缩存储
对称矩阵
在 n阶矩阵 A中,任意一个元素 ai,j,都有 ai,j=aj,i( 1≤i,j≤n,注意此处不是下标),称为对称矩阵。它分为三个区域(分别是上三角区( i<j),下三角区 ( i>j)和主对角线 i=j),若要进行压缩,只需要存储上(或下)三角区
和主对角线
即可,压缩后的元素个数为 n(n+1)2(假设以下三角区和主对角线为例,第一行需要存储 1个,第二行需要存储 2个,第 i行需要存储 i个,是个等差数列求和),将其映射成一维数组.
1.行优先且以
下三角区
和主对角线
为核心
![]()
- 第一行 1个元素;
- 第二行 2个元素;
- ⋯;
- 第 i−1行 i−1个元素;
- 第 i行 i个元素.
若想求出对应的 ai,j( i≥j)的映射一维数组下标(此处下标是从 0开始的),先计算出 ai,j前面有多少个元素(前 i−1行总共有 (i−1+1)(i−1)2=i(i−1)2个元素,第 i行有 j−1个元素);
若想求出对应的 ai,j( i<j)的映射一维数组下标(此处下标是从 0开始的),先计算出 ai,j前面有多少个元素(由于对称矩阵可看作是 i,j进行交换);
整理得:
![]()
2.行优先且以
上三角区
和主对角线
为核心
![]()
第一行 n个元素;
第二行 n−1个元素;
⋯
第 i−1行 n+1−(i−1)=n+2−i个元素;
第 i行 n+1−i个元素.
若想求出对应的 ai,j( i≤j)的映射一维数组下标(此处下标是从 0开始的),先计算出 ai,j前面有多少个元素(前 i−1行总共有 (n+n+2−i)(i−1)2=(2n−i+2)(i−1)2个元素,第 i行有 j−i个元素);
若想求出对应的 ai,j( i>j)的映射一维数组下标(此处下标是从 0开始的),先计算出 ai,j前面有多少个元素(由于对称矩阵原因可看作是 i,j进行交换);
整理得:
![]()
3.列优先且以
下三角区
和主对角线
为核心
![]()
- 第一列 n个元素;
- 第二列 n−1个元素;
⋯
第 j−1列 n+1−(j−1)=n+2−j个元素;
第 j列 n+1−j个元素.
若想求出对应的 ai,j( i≥j)的映射一维数组下标(此处下标是从 0开始的),先计算出 ai,j前面有多少个元素(前 j−1列总共有 (n+n+2−j)(j−1)2=(2n−j+2)(j−1)2个元素,第 j列有 i−j个元素);
若想求出对应的 ai,j( i<j)的映射一维数组下标(此处下标是从 0开始的),先计算出 ai,j前面有多少个元素(由于对称矩阵原因可看作是 i,j进行交换);
整理得:
![]()
4.列优先且以
上三角区
和主对角线
为核心
![]()
- 第一列 1个元素;
- 第二列 2个元素;
- ⋯;
- 第 j−1列 j−1个元素;
- 第 j列 j个元素.
若想求出对应的 ai,j( i≤j)的映射一维数组下标(此处下标是从 0开始的),先计算出 ai,j前面有多少个元素(前 j−1列总共有 (j−1+1)(j−1)2=j(j−1)2个元素,第 j列有 i−1个元素);
若想求出对应的 ai,j( i>j)的映射一维数组下标(此处下标是从 0开始的),先计算出 ai,j前面有多少个元素(由于对称矩阵可看作是 i,j进行交换);
整理得:
![]()
三角矩阵
三角矩阵分为两种,分别是上三角矩阵(下三角区的所有元素均为常量)和下三角矩阵(上三角区的所有元素均为常量),压缩无非是在对称矩阵压缩条件下再增加一个空间存储另一个区的常量,即压缩后的元素个数为 n(n+1)2+1
- 下三角矩阵
可参考对称矩阵( 1行优先, 3列优先)的存储,此处直接给出结论,不作证明
- 上三角矩阵
可参考对称矩阵( 2行优先, 4列优先)的存储,此处直接给出结论,不作证明
三对角矩阵
对角矩阵又称为带状矩阵,是指在 n×n的矩阵 a中,非零元素集中在主对角线及其两侧,共 L(奇数)条对角线的带状区域内,称为 L对角矩阵.故三对角矩阵就是 3条对角线的带状区域,可发现 当 |i−j|>1,有 ai,j=0,其中 1≤i,j≤n.压缩后的元素个数是 3×n−2
此处用行优先作例子
-
第一行 2个元素;
-
第二行 3个元素;
-
⋯
-
第 i−1行有 3个元素;
若想求出对应的 ai,j( |i−j|≤1)的映射一维数组下标(此处下标是从 0开始的),先计算出 ai,j前面有多少个元素(前 i−1行总共有 2+3×(i−2)=3i−4个元素,第 i行有 j−1−i+2=j−i+1个元素);
整理得:
![]()
特殊考虑第一行代入公式亦成立,即 pos=2×i+j−3.
若已知 pos能否求出对应的 i,j, i=(pos+1)3+1(可尝试代入 a1,1,a1,2,a2,1体会),同理 j可通过上述公式求出 j=pos−2×i+3
稀疏矩阵
设矩阵元素个数为 m ,非零元素的个数为 n,其中非零元素极少,即 n≪m,称为稀疏矩阵.只存储非零元素
进行空间压缩
- 三元组(行标,列标,值) ——顺序存储
- 十字链表 ——链式存储
i,j,value分别代表非零元素所在的行号、列号和相应的元素值; down和 right分别称为向下指针和向右指针,分别用来链接同列中和同行中的下一个非零元素结点。
![]()
3.4.3
有一个 n×n的对称矩阵 A,将其下三角部分按行存放在一维数组 B中,而 A[0][0]存放于 B[0]中,则第 i+1行的对角元素 A[i][i]存放于 B中的()处.
A. (i+3)i2
B. (i+1)i2
C. (2n−i+1)i2
D. (2n−i−1)i2
矩阵行数(从1开始) | 对应下标行(从0开始) | 行元素个数 |
---|---|---|
1 | 0 | 1 |
2 | 1 | 2 |
3 | 2 | 3 |
⋯ | ⋯ | ⋯ |
i−1 | i−2 | i−1 |
i | i−1 | i |
i+1 | i | i+1 |
计算 Ai,i(即矩阵第 i+1行的第 i+1个元素)前面的元素个数(矩阵前 i行共有 (i+1)×i2, 在矩阵第 i+1当前行有 i个元素,总共 (i+1)×i2+i=i2+3i2=(i+3)×i2)
3.4.4
在一个二维数组 A中,假设每个数组元素的长度为 3个存储单元,行下标 i为 0∼8, 列下标 j为 0∼9,从首地址 SA开始连续存放。在这种情况下,元素 A[8][5]的起始地址为().
A. SA+141
B. SA+144
C. SA+222
D. SA+255
二维数组 A(有 9行, 10列),套公式 LOC(ai,j)=LOC(a0,0)+(i×m+j)×L,代入得 LOC(a8,5)=SA+(8×10+5)×3=SA+255
3.4.5
将三对角矩阵 A[1,⋯,100][1,⋯,100]按行优先存入一维数组 B[1,⋯,298]中, A中元素 A[66][65]在数组 B中的位置 k为().
A. 198
B. 195
C. 197
D. 196
注意 B数组下标是从 1开始的,套用三对角矩阵的结论(适用于 B数组下标从 0开始), pos=2×i+j−3,故 k=pos+1=2×i+j−2,代入得: 2×66+65−2=132+63=195.
3.4.6
若将 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
套上三角矩阵结论和k=pos+1
思想
最终结果为 pos=j(j−1)2+i−1, k=pos+1=j(j−1)2+i
3.4.7
若将 n阶下三角矩阵 A按列优先级压缩存放在一维数组 B[1,⋯,n(n+1)2+1]中,则存放到 B[k]中的非零元素 ai,j ( 1≤i,j≤n)的下标 i、 j与 k的对应关系是().
A. (j−1)(2n−j+1)2+i−j
B. (j−1)(2n−j+2)2+i−j+1
C. (j−1)(2n−j+2)2+i−j
D. (j−1)(2n−j+1)2+i−j−1
套下三角矩阵结论和k=pos+1
思想
最终结果为 pos=(2n−j+2)(j−1)2+i−j, k=pos+1=(2n−j+2)(j−1)2+i−j+1
3.4.8
2016统考真题:有一个 100阶的三对角矩阵 M,其元素 mi,j ( 1≤i,j≤100),按行优先依次压缩存入下标从 0开始的一维数组 N中。元素 m30,30在 N中的下标是().
A. 86
B. 87
C. 88
D. 89
套三对角矩阵公式 pos=2×i+j−3=2×30+30−3=87.
3.4.10
2018统考真题:设有一个 12×12的对称矩阵 M,将其上三角部分的元素 mi,j( 1≤i≤j≤12)按行优先存入 C语言的一维数组 N中,元素 m6,6在 N中的下标是() .
A. 50
B. 51
C. 55
D. 66
由于 m6,6位于上三角区,套对称矩阵公式得 pos=(2n−i+2)(i−1)2+j−i=20×52=50
3.4.11
2020统考真题:设有一个 10×10的对称矩阵 M,将其上三角部分的元素 mi,j( 1≤i≤j≤10)按列优先存入 C语言的一维数组 N中,元素 m7,2在 N中的下标是() .
A. 15
B. 16
C. 22
D. 23
由于 m7,2位于下三角区,套对称矩阵公式得 pos=i(i−1)2+j−1=7×62+1=22
3.4.12
已知二维数组 A按行优先方法存储,每个元素占用 1个存储单元,起始地址 A[0][0]为 100,若元素 A[3][3]的存储地址是 220,则元素 A[5][5]的存储地址是?
A. 295
B. 300
C. 301
D. 306
由该公式 LOC(ai,j)=LOC(a0,0)+(i×m+j)×L得: LOC(a3,3)=220=100+(3×m+3)×1
解得: m=39
因此可求出: LOC(a5,5)==100+(5×39+5)×1=100+200=300