5.1数组的类型定义
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
13
(1)数组A的体积(即存储量) 解:存储量=6×8×6=288 (2)数组A的最后一个元素a57的第一个字 节的地址; 解:LOC( a57 )=1000+288-6=1282
14
(3)假设按行存储时,元素a14的第一个 字节的地址; 解:LOC(a14)=LOC(a00)+(8×1+4)×6 =1000+72=1072 (4)假设按列存储时,元素a47的第一个 字节的地址; 解:LOC(a47)=LOC(a00)+(6×7+4)×6 =1000+276=1276
一、三元组顺序表 二、行逻辑联接的顺序表 三、十字链表
24
一、三元组顺序表
#define MAXSIZE 12500 typedef struct { int i, j; //该非零元的行下标和列下标 ElemType e; // 该非零元的值 } Triple; // 三元组类型 typedef union { Triple data[MAXSIZE + 1]; int mu, nu, tu; } TSMatrix; // 稀疏矩阵类型
#define MAXMN 500 typedef struct { Triple data[MAXSIZE + 1]; int rpos[MAXMN + 1]; int mu, nu, tu; } RLSMatrix; // 行逻辑链接顺序表类型
39
• 图4-6
(矩阵T)
40
例如:给定一组下标,求矩阵的元素值
0<=(i,j)<n
②上三角矩阵中有A[i][j]与B[k] 的对应关 系如下:
k=i*(2*n-i+1)/2+j-i
0<=(i,j)<n
21
对称矩阵
满足性质:aij=aji 0<=(i, j)<=n 在存储时我们可以为每一对对称元素分 配一个存储空间,则可将n2个元素压缩 存储到n(n+1)/2个元的空间中。我们可以 参照下三角以行优先存储。 A[i][j]与B[k] 的对应关系如下: i*(i+1)/2+j 当i>=j ,0<=(i, j)<=n (下三角) k= j*(j+1)/2+i 当i<j, 0<=(i, j)<=n (上三角)
15
5.3 矩阵的压缩存储
何谓稀疏矩阵?
假设 m 行 n 列的矩阵含 t 个非零元素, 则称
mt n
为稀疏因子
通常认为 0.05 的矩阵为稀疏矩阵
16
怎样才能解决这些问题?
以常规方法,即以二维数组表示
高阶的稀疏矩阵时产生的问题: 1) 零值元素占了很大空间;
2) 计算中进行了很多和零值的运算, 遇乘法,白乘;遇除法,还需判别除数
时间复杂度为: O(M.nu+M.tu)
35
预习题
1.特殊矩阵和稀疏矩阵哪一种压缩存储后会失 去随机存储功能?为什么? 2.什么叫广义表?它和线性表有和相同和不同 之处? 3.什么叫广义表的表头、表尾、表长、表深? 4.广义表适合使用顺序还是链式存储?
ຫໍສະໝຸດ Baidu
36
二、行逻辑联接的顺序表 三元组顺序表又称有序的双下标 法,它的特点是,非零元在表中按行 序有序存储,因此便于进行依行顺序 处理的矩阵运算。然而,若需随机存 取某一行中的非零元,则需从头开始 进行查找。
ElemType value(RLSMatrix M, int r, int c) { p = M.rpos[r]; while (M.data[p].i==r &&M.data[p].j < c) p++; if (M.data[p].i==r && M.data[p].j==c) return M.data[p].e; else return 0; 时间复杂度为O(c) 接近于常数阶,具有一定随机存储特征 } // value
32
Status FastTransposeSMatrix(TSMatrix M, TSMatrix &T){
T.mu = M.nu; T.nu = M.mu; T.tu = M.tu; if (T.tu) { for (col=1; col<=M.nu; ++col) num[col] = 0; for (t=1; t<=M.tu; ++t) ++num[M.data[t].j]; cpot[1] = 1; for (col=2; col<=M.nu; ++col) cpot[col] = cpot[col-1] + num[col-1]; for (p=1; p<=M.tu; ++p) { 转置矩阵元素 } } // if return OK; } // FastTransposeSMatrix 33
37
为了便于随机存取任意一行 的非零元,则需知道每一行的第 一个非零元在三元组表的位置 (位序)。因此,可以将此指示 “行”信息的辅助数组固定在稀 疏矩阵的三元组表结构里面。
38
修改前述的稀疏矩阵的结构定义, 增加一个数据成员rpos, 其值在稀疏矩 阵的初始化函数中确定(目的是增加其 随机存储特性)。
素存储位置的映象关系
LOC(j1, j2, ..., jn ) = LOC(0,0,...,0) + ∑ c j i i =1 i
n
其中 cn = L,ci-1 = bi ×ci , 1 < i n。
称为 n 维数组的映象函数。数组元素
的存储位置是其下标的线性函数
12
课堂练习
• 假设c语言中有二维数组A6×8,每个元素用 相邻的6个字节存储,存储器按字节编址。 已知A的起始存储位置为1000,计算: (1)数组A的体积(即存储量) (2)数组A的最后一个元素a57的第一个字 节的地址; (3)假设按行存储时,元素a14的第一个字 节的地址; (4)假设按列存储时,元素a47的第一个字 节的地址。
M
0 0 36 14 7 0 0 0 0 0 0 28 5 0 0
T
27
用常规的二维数组表示时的算法
for (col=1; col<=nu; ++col)
for (row=1; row<=mu; ++row)
T[col][row] = M[row][col];
4
基本操作:
InitArray(&A, n, bound1, ..., boundn)
DestroyArray(&A)
Value(A, &e, index1, ..., indexn) Assign(&A, e, index1, ..., indexn)
5
InitArray(&A, n, bound1, ..., boundn) 操作结果:若维数 n 和各维长度合法, 则构造相应的数组A,并 返回OK。
22
三对角矩阵
将其3条对角线上的元素存于数组B[3n-2-1] 中,使得B[k] = A[i][j] ,A[i][j]与B[k] 的对应 关系如下(请推导):
k = f(i, j)= ? k=2i+j |i-j|<=1
k=1+ 3(i-1)+ (j-i+2) =2i+j
23
随机稀疏矩阵的压缩存储方法:
31
那么如何确定每一行的第一个非零 元在三元组中的位置?
1 1 2 3 3 2 15 5 -5 col 1 2 3 4 5 2 -7 Num[pos] 1 2 0 1 1 1 36 Cpot[col] 1 2 4 4 5 4 28 M的第col列的第一个非零元转置后在T的位置 cpot[1] = 1; for (col=2; col<=M.nu; ++col) cpot[col] = cpot[col-1] + num[col-1];
是否为零;
17
解决问题的原则:
1) 尽可能少存或不存零值元素;
2) 尽可能减少没有实际意义的运算;
3) 操作方便; 即: a.能尽可能快地找到与下标值(i,j) 对应的元素; b.能尽可能快地找到同一行或同 一列的非零值元;
18
有两类稀疏矩阵:
1) 特殊矩阵
非零元在矩阵中的分布有一定规则
例如: 三角矩阵
Col = M.data[p].j; q = cpot[col];//转置后的位置 T.data[q].i = M.data[p].j; T.data[q].j = M.data[p].i; T.data[q].e = M.data[p].e; ++cpot[col]//第col列下一非零元的位置
10
以“行序为主序”的存储映象
例如:
a0,0 a0,1 a0,2 a1,0 a1,1 a1,2
a0,0 a0,1 a0,2 a1,0 a1,1 a1,2
L
二维数组A中任一元素ai,j 的存储位置
LOC(i,j) = LOC(0,0) + (b2×i+j)×L
称为基地址或基址。
11
推广到一般情况,可得到 n 维数组数据元
对角矩阵 2) 随机稀疏矩阵
非零元在矩阵中随机出现
19
三角矩阵
k=1+2+…+i+j k=n+(n-1)+…+(n-i)+(j-i)
20
三角矩阵
将A[n][n],把它的非0元按行优先, 逐行、逐个存入 B[n*(n+1)/2]中) ①下三角矩阵中有A[i][j]与B[k] 的对应关 系如下:
k= i*(i+1)/2+j
其时间复杂度为: O(mu×nu)
28
用“三元组”表示时如何实现? 1 1 2 3 3 2 14 5 -5 2 -7 1 36 4 28 M 1 2 2 4 5 3 36 1 14 2 -7 3 28 1 -5 T
29
i 1 1 2 3 3
i 1 2 2 4 5
j 2 5 2 1 4
j 3 1 2 3 1
25
矩阵M:
三元组表(行优先):
1 1 2 3 3 3 2 5 2 1 4 5 14 -5 -7 36 28 5
0 14 0 0 5 0 7 0 0 0 36 0 0 28 0
26
如何求转置矩阵?
将第i行j列元素变为第j行i列元素
0 14 0 0 5 0 7 0 0 0 36 0 0 28 0
6
DestroyArray(&A) 操作结果:销毁数组A。
7
Value(A, &e, index1, ..., indexn)
初始条件:A是n维数组,e为元素变量,
随后是n 个下标值。 操作结果:若各下标不超界,则e赋值为 所指定的A 的元素值,并返 回OK。
8
Assign(&A, e, index1, ..., indexn)
初始条件:A是n维数组,e为元素变量, 随后是n 个下标值。 操作结果:若下标不超界,则将e的值赋 给所指定的A的元素,并返回 OK。
9
5.2 数组的顺序表示和实现
类型特点: 1) 只有引用型操作,没有加工型操作; 2) 数组是多维的结构,而存储空间是 一个一维的结构。
有两种顺序映象的方式: 1)以行序为主序(低下标优先); 2)以列序为主序(高下标优先);
v 14 -5 -7 36 28
v 36 14 -7 28 -5
M
行列值互换
思路一
i 2 5 2 1 4 j 1 1 2 3 3 v 14 -5 -7 36 28
按行优先重排 三元组次序
T
30
思路二
按照M.data中三元组的次序进 行转置,并将转置后置入T中恰当的 位置。要找到这个恰当位置,必须 预先知道M中每一列的非零元在T中 的位置。
1
5.1 5.2 5.3 5.4 5.5
数组的类型定义 数组的顺序表示和实现 稀疏矩阵的压缩存储 广义表的类型定义 广义表的表示方法
2
5.6 广义表操作的递归函数
5.1 数组的类型定义
ADT Array { 数据对象: D={aj ,j , ...,,j ,j | ji =0,...,bi -1, i=1,2,..,n } 数据关系: R={R1, R2, ..., Rn} Ri={<aj ,... j ,... j , aj , ...j +1, ...j > | 0 jk bk -1, 1 k n 且k i, 0 ji bi -2, i=2,...,n } 基本操作: } ADT Array
1 2 i n 1 i n 1 i n
3
二维数组的定义: 数据对象: D = {aij | 0≤i≤b1-1, 0 ≤j≤b2-1}
数据关系:
R = { ROW, COL }
ROW = {<ai,j,ai+1,j>| 0≤i≤b1-2, 0≤j≤b2-1}
COL = {<ai,j,ai,j+1>| 0≤i≤b1-1, 0≤ j≤b2-2}
34
分析算法FastTransposeSMatrix的时 间复杂度:
for (col=1; col<=M.nu; ++col) … … for (t=1; t<=M.tu; ++t) … … for (col=2; col<=M.nu; ++col) … … for (p=1; p<=M.tu; ++p) … …
(1)数组A的体积(即存储量) 解:存储量=6×8×6=288 (2)数组A的最后一个元素a57的第一个字 节的地址; 解:LOC( a57 )=1000+288-6=1282
14
(3)假设按行存储时,元素a14的第一个 字节的地址; 解:LOC(a14)=LOC(a00)+(8×1+4)×6 =1000+72=1072 (4)假设按列存储时,元素a47的第一个 字节的地址; 解:LOC(a47)=LOC(a00)+(6×7+4)×6 =1000+276=1276
一、三元组顺序表 二、行逻辑联接的顺序表 三、十字链表
24
一、三元组顺序表
#define MAXSIZE 12500 typedef struct { int i, j; //该非零元的行下标和列下标 ElemType e; // 该非零元的值 } Triple; // 三元组类型 typedef union { Triple data[MAXSIZE + 1]; int mu, nu, tu; } TSMatrix; // 稀疏矩阵类型
#define MAXMN 500 typedef struct { Triple data[MAXSIZE + 1]; int rpos[MAXMN + 1]; int mu, nu, tu; } RLSMatrix; // 行逻辑链接顺序表类型
39
• 图4-6
(矩阵T)
40
例如:给定一组下标,求矩阵的元素值
0<=(i,j)<n
②上三角矩阵中有A[i][j]与B[k] 的对应关 系如下:
k=i*(2*n-i+1)/2+j-i
0<=(i,j)<n
21
对称矩阵
满足性质:aij=aji 0<=(i, j)<=n 在存储时我们可以为每一对对称元素分 配一个存储空间,则可将n2个元素压缩 存储到n(n+1)/2个元的空间中。我们可以 参照下三角以行优先存储。 A[i][j]与B[k] 的对应关系如下: i*(i+1)/2+j 当i>=j ,0<=(i, j)<=n (下三角) k= j*(j+1)/2+i 当i<j, 0<=(i, j)<=n (上三角)
15
5.3 矩阵的压缩存储
何谓稀疏矩阵?
假设 m 行 n 列的矩阵含 t 个非零元素, 则称
mt n
为稀疏因子
通常认为 0.05 的矩阵为稀疏矩阵
16
怎样才能解决这些问题?
以常规方法,即以二维数组表示
高阶的稀疏矩阵时产生的问题: 1) 零值元素占了很大空间;
2) 计算中进行了很多和零值的运算, 遇乘法,白乘;遇除法,还需判别除数
时间复杂度为: O(M.nu+M.tu)
35
预习题
1.特殊矩阵和稀疏矩阵哪一种压缩存储后会失 去随机存储功能?为什么? 2.什么叫广义表?它和线性表有和相同和不同 之处? 3.什么叫广义表的表头、表尾、表长、表深? 4.广义表适合使用顺序还是链式存储?
ຫໍສະໝຸດ Baidu
36
二、行逻辑联接的顺序表 三元组顺序表又称有序的双下标 法,它的特点是,非零元在表中按行 序有序存储,因此便于进行依行顺序 处理的矩阵运算。然而,若需随机存 取某一行中的非零元,则需从头开始 进行查找。
ElemType value(RLSMatrix M, int r, int c) { p = M.rpos[r]; while (M.data[p].i==r &&M.data[p].j < c) p++; if (M.data[p].i==r && M.data[p].j==c) return M.data[p].e; else return 0; 时间复杂度为O(c) 接近于常数阶,具有一定随机存储特征 } // value
32
Status FastTransposeSMatrix(TSMatrix M, TSMatrix &T){
T.mu = M.nu; T.nu = M.mu; T.tu = M.tu; if (T.tu) { for (col=1; col<=M.nu; ++col) num[col] = 0; for (t=1; t<=M.tu; ++t) ++num[M.data[t].j]; cpot[1] = 1; for (col=2; col<=M.nu; ++col) cpot[col] = cpot[col-1] + num[col-1]; for (p=1; p<=M.tu; ++p) { 转置矩阵元素 } } // if return OK; } // FastTransposeSMatrix 33
37
为了便于随机存取任意一行 的非零元,则需知道每一行的第 一个非零元在三元组表的位置 (位序)。因此,可以将此指示 “行”信息的辅助数组固定在稀 疏矩阵的三元组表结构里面。
38
修改前述的稀疏矩阵的结构定义, 增加一个数据成员rpos, 其值在稀疏矩 阵的初始化函数中确定(目的是增加其 随机存储特性)。
素存储位置的映象关系
LOC(j1, j2, ..., jn ) = LOC(0,0,...,0) + ∑ c j i i =1 i
n
其中 cn = L,ci-1 = bi ×ci , 1 < i n。
称为 n 维数组的映象函数。数组元素
的存储位置是其下标的线性函数
12
课堂练习
• 假设c语言中有二维数组A6×8,每个元素用 相邻的6个字节存储,存储器按字节编址。 已知A的起始存储位置为1000,计算: (1)数组A的体积(即存储量) (2)数组A的最后一个元素a57的第一个字 节的地址; (3)假设按行存储时,元素a14的第一个字 节的地址; (4)假设按列存储时,元素a47的第一个字 节的地址。
M
0 0 36 14 7 0 0 0 0 0 0 28 5 0 0
T
27
用常规的二维数组表示时的算法
for (col=1; col<=nu; ++col)
for (row=1; row<=mu; ++row)
T[col][row] = M[row][col];
4
基本操作:
InitArray(&A, n, bound1, ..., boundn)
DestroyArray(&A)
Value(A, &e, index1, ..., indexn) Assign(&A, e, index1, ..., indexn)
5
InitArray(&A, n, bound1, ..., boundn) 操作结果:若维数 n 和各维长度合法, 则构造相应的数组A,并 返回OK。
22
三对角矩阵
将其3条对角线上的元素存于数组B[3n-2-1] 中,使得B[k] = A[i][j] ,A[i][j]与B[k] 的对应 关系如下(请推导):
k = f(i, j)= ? k=2i+j |i-j|<=1
k=1+ 3(i-1)+ (j-i+2) =2i+j
23
随机稀疏矩阵的压缩存储方法:
31
那么如何确定每一行的第一个非零 元在三元组中的位置?
1 1 2 3 3 2 15 5 -5 col 1 2 3 4 5 2 -7 Num[pos] 1 2 0 1 1 1 36 Cpot[col] 1 2 4 4 5 4 28 M的第col列的第一个非零元转置后在T的位置 cpot[1] = 1; for (col=2; col<=M.nu; ++col) cpot[col] = cpot[col-1] + num[col-1];
是否为零;
17
解决问题的原则:
1) 尽可能少存或不存零值元素;
2) 尽可能减少没有实际意义的运算;
3) 操作方便; 即: a.能尽可能快地找到与下标值(i,j) 对应的元素; b.能尽可能快地找到同一行或同 一列的非零值元;
18
有两类稀疏矩阵:
1) 特殊矩阵
非零元在矩阵中的分布有一定规则
例如: 三角矩阵
Col = M.data[p].j; q = cpot[col];//转置后的位置 T.data[q].i = M.data[p].j; T.data[q].j = M.data[p].i; T.data[q].e = M.data[p].e; ++cpot[col]//第col列下一非零元的位置
10
以“行序为主序”的存储映象
例如:
a0,0 a0,1 a0,2 a1,0 a1,1 a1,2
a0,0 a0,1 a0,2 a1,0 a1,1 a1,2
L
二维数组A中任一元素ai,j 的存储位置
LOC(i,j) = LOC(0,0) + (b2×i+j)×L
称为基地址或基址。
11
推广到一般情况,可得到 n 维数组数据元
对角矩阵 2) 随机稀疏矩阵
非零元在矩阵中随机出现
19
三角矩阵
k=1+2+…+i+j k=n+(n-1)+…+(n-i)+(j-i)
20
三角矩阵
将A[n][n],把它的非0元按行优先, 逐行、逐个存入 B[n*(n+1)/2]中) ①下三角矩阵中有A[i][j]与B[k] 的对应关 系如下:
k= i*(i+1)/2+j
其时间复杂度为: O(mu×nu)
28
用“三元组”表示时如何实现? 1 1 2 3 3 2 14 5 -5 2 -7 1 36 4 28 M 1 2 2 4 5 3 36 1 14 2 -7 3 28 1 -5 T
29
i 1 1 2 3 3
i 1 2 2 4 5
j 2 5 2 1 4
j 3 1 2 3 1
25
矩阵M:
三元组表(行优先):
1 1 2 3 3 3 2 5 2 1 4 5 14 -5 -7 36 28 5
0 14 0 0 5 0 7 0 0 0 36 0 0 28 0
26
如何求转置矩阵?
将第i行j列元素变为第j行i列元素
0 14 0 0 5 0 7 0 0 0 36 0 0 28 0
6
DestroyArray(&A) 操作结果:销毁数组A。
7
Value(A, &e, index1, ..., indexn)
初始条件:A是n维数组,e为元素变量,
随后是n 个下标值。 操作结果:若各下标不超界,则e赋值为 所指定的A 的元素值,并返 回OK。
8
Assign(&A, e, index1, ..., indexn)
初始条件:A是n维数组,e为元素变量, 随后是n 个下标值。 操作结果:若下标不超界,则将e的值赋 给所指定的A的元素,并返回 OK。
9
5.2 数组的顺序表示和实现
类型特点: 1) 只有引用型操作,没有加工型操作; 2) 数组是多维的结构,而存储空间是 一个一维的结构。
有两种顺序映象的方式: 1)以行序为主序(低下标优先); 2)以列序为主序(高下标优先);
v 14 -5 -7 36 28
v 36 14 -7 28 -5
M
行列值互换
思路一
i 2 5 2 1 4 j 1 1 2 3 3 v 14 -5 -7 36 28
按行优先重排 三元组次序
T
30
思路二
按照M.data中三元组的次序进 行转置,并将转置后置入T中恰当的 位置。要找到这个恰当位置,必须 预先知道M中每一列的非零元在T中 的位置。
1
5.1 5.2 5.3 5.4 5.5
数组的类型定义 数组的顺序表示和实现 稀疏矩阵的压缩存储 广义表的类型定义 广义表的表示方法
2
5.6 广义表操作的递归函数
5.1 数组的类型定义
ADT Array { 数据对象: D={aj ,j , ...,,j ,j | ji =0,...,bi -1, i=1,2,..,n } 数据关系: R={R1, R2, ..., Rn} Ri={<aj ,... j ,... j , aj , ...j +1, ...j > | 0 jk bk -1, 1 k n 且k i, 0 ji bi -2, i=2,...,n } 基本操作: } ADT Array
1 2 i n 1 i n 1 i n
3
二维数组的定义: 数据对象: D = {aij | 0≤i≤b1-1, 0 ≤j≤b2-1}
数据关系:
R = { ROW, COL }
ROW = {<ai,j,ai+1,j>| 0≤i≤b1-2, 0≤j≤b2-1}
COL = {<ai,j,ai,j+1>| 0≤i≤b1-1, 0≤ j≤b2-2}
34
分析算法FastTransposeSMatrix的时 间复杂度:
for (col=1; col<=M.nu; ++col) … … for (t=1; t<=M.tu; ++t) … … for (col=2; col<=M.nu; ++col) … … for (p=1; p<=M.tu; ++p) … …