5数组和广义表

合集下载

第5章数组和广义表PPT课件

第5章数组和广义表PPT课件
A、j(j-1)/2+i-1 B、j(j-1)/2+i C、j(j+1)/2+i-1 D、 j(j+1)/2+i
数据结构(Java版)》叶核亚
5.2.2 稀疏矩阵的压缩存储
表示稀疏矩阵的三元组
0 0 11 0 17 0
0
20
0
0
0
0
行号 row
列号 column
元素值 value
A56
0 19
设矩阵A是一个对称矩阵,为了节省空间,将其下三角部分 按行优先存放在一维数组B中。对下三角矩阵中任一元素 aij(i>=j,j>=1),在一维数组B中下标K的值是:
A、i(i-1)/2+j-1 B、i(i-1)/2+j C、i(i+1)/2+j-1 D、 i(i+1)/2+j
设矩阵A是一个对称矩阵,为了节省空间,将其上三角部分 按列优先存放在一维数组B中。对上三角矩阵中任一元素 aij(i<=j,i>=1),在一维数组B中下标K的值是:
1.多维数组的逻辑结构
数据结构(Java版)》叶核亚
5.1.2 多维数组
2.多维数组的遍历
(1)行优先次序
a1,1 a1,2 a1,n
Amn
a2,1
am,1
a2,2 am,2
a2,n
am,n
a1,1,a1,2,…,a1,n,a2,1,a2,2,…, a2,n,…,am,1,am,2,…,am,n
常见的广义表为:
L=(a,b)
//线性表,长度为2 ,深度为1
T=(c,L)=(c,(a,b)) //L为T的子表,T的长度为2 , 深度为2

《数据结构——用C语言描述(第二版)》第5章 数组和广义表

《数据结构——用C语言描述(第二版)》第5章  数组和广义表
是指矩阵的下三角(不含对角线)中的元素均为常数C或零的n阶矩阵,下 三角矩阵则与之相反,如图5.3所示。
第五章 数组和广义表
在压缩存储时,矩阵中值相同的元素C可共享一个存储空间,元素 为零则可不必分配空间,而其余的元素有 n(n+1)/2个,因此三角矩阵 可用一维数组M[n×(n+1)/2+1]来存储,其中常数C放在数组的最后一 个下标变量中。
假设A和B矩阵分别用matrix型指针变量a和b表示,矩阵的转置可以 按以下进行:由于B的行是A的列,所以可按照b->data三元组表的次序在 a->data中找到相应的三元组进行转置,即可按a->data的列序转置,所得 到的转置矩阵B的三元组表b->data必定是按行优先存放的。因此,可以对 三元组表a->data从第一行起扫描,找到A的每一列中所有的非零元素,就 可以实现转置。
LOC ( aij ) =LOC ( a00) +(i×n+j) × c 同理可推导出以列为主序优先存储时数据元素a i j 的存储地址,其计算公式 为:
LOC( a i j ) =LOC( a00 ) +( j × n +i ) × c 对于三维数组Am×n×p而言,若以行为主序优先存储时,则其数据元 素aijk的存储地址可为: LOC ( a i j k) =LOC ( a000) +[ i × m×p +j ×p +k] × c 对于一般的二维数组A[c1…d1,c2…d2]而言,此处c1,c2的值不一定是 0,a i j 的地址为: LOC ( a i j ) =LOC ( a c 1 c 2 ) +[ ( i – c 1 )* ( d 2 – c 2 +1) +j – c 2 ] * c

数据结构第5章

数据结构第5章

第5章:数组和广义表 1. 了解数组的定义;填空题:1、假设有二维数组A 6×8,每个元素用相邻的6个字节存储,存储器按字节编址。

已知A 的起始存储位置(基地址)为1000,则数组A 的体积(存储量)为 288 B ;末尾元素A 57的第一个字节地址为 1282 。

2、三元素组表中的每个结点对应于稀疏矩阵的一个非零元素,它包含有三个数据项,分别表示该元素的 行下标 、 列下标 和 元素值 。

2. 理解数组的顺序表示方法会计算数组元素顺序存储的地址;填空题:1、已知A 的起始存储位置(基地址)为1000,若按行存储时,元素A 14的第一个字节地址为 (8+4)×6+1000=1072 ;若按列存储时,元素A 47的第一个字节地址为 (6×7+4)×6+1000)=1276 。

(注:数组是从0行0列还是从1行1列计算起呢?由末单元为A 57可知,是从0行0列开始!) 2、设数组a[1…60, 1…70]的基地址为2048,每个元素占2个存储单元,若以列序为主序顺序存储,则元素a[32,58]的存储地址为 8950 。

答:不考虑0行0列,利用列优先公式: LOC(a ij )=LOC(a c 1,c 2)+[(j-c 2)*(d 1-c 1+1)+i-c 1)]*L 得:LOC(a 32,58)=2048+[(58-1)*(60-1+1)+32-1]]*2=8950选择题:( A )1、假设有60行70列的二维数组a[1…60, 1…70]以列序为主序顺序存储,其基地址为10000,每个元素占2个存储单元,那么第32行第58列的元素a[32,58]的存储地址为 。

(无第0行第0列元素)A .16902B .16904C .14454D .答案A, B, C 均不对 答:此题(57列×60行+31行)×2字节+10000=16902( B )2、设矩阵A 是一个对称矩阵,为了节省存储,将其下三角部分(如下图所示)按行序存放在一维数组B[ 1, n(n-1)/2 ]中,对下三角部分中任一元素a i,j (i ≤j), 在一维数组B 中下标k 的值是:A .i(i-1)/2+j-1B .i(i-1)/2+jC .i(i+1)/2+j-1D .i(i+1)/2+j3、从供选择的答案中,选出应填入下面叙述 ? 内的最确切的解答,把相应编号写在答卷的对应栏内。

数组和广义表 数据结构

数组和广义表  数据结构

3.建立广义表的存储结构 假定广义表中的元素类型ElemType为chai类型,每个原子的值被限 定为英文字母。并假定广义表是一个表达式,其格式为:元素之间用一 个逗号分隔,表元素的起止符号分别为左、右圆括号,空表在其圆括号 内不包含任何字符。例如“(a,(b, c, d))”就是一个符合上述规定的广 义表格式。 建立广义表存储结构的算法同样是一个递归算法。该算法使用一个 具有广义表格式的字符串参数s,返回由它生成的广义表存储结构的头结 点指针h。在算法的执行过程中,需要从头到尾扫描s的每一个字符。当 碰到左括号时,表明它是一个表元素的开始,则应建立一个由h指向的表 结点,并用它的sublist域作为子表的表头指针进行递归调用,来建立子 表的存储结构;当碰到一个英文字母时,表明它是一个原子,则应建立 一个由h指向的原子结点;当碰到一个“)”字符时,表明它是一个空表, 则应置h为空。当建立了一个由h指向的结点后,接着碰到逗号字符时, 表明存在后继结点,需要建立当前结点(即由h指向的结点)的后继表; 当碰到右括号或分号字符时,表明当前所处理的表已结束,应该置当前 结点的link域为空。 4.输出广义表 5.广义表的复制
广义表的转换过程
为了使子表和原子两类结点既能在形式上保持一致,又能进
行区别,可采用如下结构形式:
其中,tag域为标志字段,用于区分两类结点。sublist或data
域由tag决定。若tag=0,表示该结点为原子结点,则第二个 域为data,存放相应原子元素的信息;若tag=l,表示该结点 为表结点,则第二个域为sublist,存放相应子表第一个元素 对应结点的地址。link域存放与本元素同一层的下一个元素所 在结点的地址,当本元素是所在层的最后一个元素时,link域 为NULL。 例:前面的广义表C的存储结构如下图所示(很多《数据结构 公教科书上称之为带表头结点的广义表的链表存储结构

第5章数组和广义表

第5章数组和广义表
//L=1,指针的增减以元素的大小为单位 For(i=dim-2;i>0;--i)
A.contants[i]=A.bounds[i+1]*A.constants[i+1]; return ok; }
第5章 数组和广义表
Status DestoryArray(Array &A){ //销毁数组 if(!A.base) return ERROR; free(A.base); A.base=NULL; if(!A.bounds) return ERROR; free(A.bounds); A.bounds=NULL; if(!A.contants) return ERROR; free(A.contants) A.contants=NULL; return ok;
(3) Value(A,&e, index1, …, indexn): 若下标合法,则 用e返回数组A中由index1, …, indexn所指定的元素的值。
(4) Assign(&A,e,indexl,…indexn):若各下标不超界, 则将e赋值为所指定的A的元素值,并返回OK。 。
第5章 数组和广义表
三维数组A(1..r , 1..m , 1..n)可以看成是r个m×n的二维数组,
如图5.5所示。
n
m n
r j- 1
m
k- 1
图5.5 三维数组看成r个m×n的二维数组
第5章 数组和广义表
假定每个元素占一个存储单元,采用以行为主序的方法存 放,即行下标r变化最慢, 纵下标n变化最快。 首元素a111的地 址为Loc[1, 1, 1],求任意元素aijk的地址。
第5章 数组和广义表
以上我们以二维数组为例介绍了数组的结构特性,实际 上数组是一组有固定个数的元素的集合。也就是说,一旦定 义了数组的维数和每一维的上下限,数组中元素的个数就固 定了。 例如二维数组A3×4,它有3行、4列,即由12个元素组 成。由于这个性质,使得对数组的操作不像对线性表的操作 那样可以在表中任意一个合法的位置插入或删除一个元素。 对于数组的操作一般只有两类:

数据结构课件PPT数组和广义表

数据结构课件PPT数组和广义表
T.mu=M.nu; T.nu=M.mu; T.tu=M.tu; if (T.tu)
{ q=1; for (col=1;col<=T.mu;++col) for(p=1;p<=M.tu;++p) if ( M.data[p].j==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; ++q; } }
(row) (col) (value)
[0] 1 4 22
[0] 1 5 91
[1] 1 7 15
[1] 2 2 11
[2] 2 2 11
[2] 3 6 28
[3] 2 [4] 3来自6 17 4 -6[3] 4 [4] 4
1 22 3 -6
[5] 4 6 39
[5] 6 2 17
[6] 5 1 91
[6] 6 4 39
cpot[1]=1 cpot[col]=cpot[col-1]+num[col-1]
稀疏矩阵的快速转置(算法5.2)
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) { 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]; } }

第5 章数组和广义表

第5 章数组和广义表

0 12 9 0 0 0 0 0 0 0 00 0 0
M6×7= -3 0 0 0 0 14 0
0 0 24 0 0 0 0 0 18 0 0 0 0 0 15 0 0 -7 0 0 0
2019/10/17
N6×7=
0 0 3 0 0 15 12 0 0 0 18 0 9 0 0 24 0 0 0 0 0 0 0 -7 0 00 0 0 0 0 0 14 0 0 0 0 0 0 00 0
Loc[i,j,k]=Loc[1,1,1]+(i-1)*m*n+(j-1)*n+(k-1) 其中1≤i≤r,1≤j≤m,1≤k≤n。
2019/10/17
14
如果将三维数组推广到一般情况,即:用j1,j2, j3代替数组下标i,j,k;并且j1,j2,j3的下限为c1, c2,c3,上限分别为d1,d2,d3,每个元素占一个 存储单元。则三维数组中任意元素 a(j1,j2,j3)的地址为:
所需的空间大小为:3n-2。
2. 确定非零元素在一维数组空间中的位置
假设每个非零元素所占的空间的大小为1个单元 LOC[i , j] = LOC[1,1]+2(i-1)+j-1
2019/10/17
22
5.3.3 稀疏矩阵
稀疏矩阵:指矩阵中大多数元素为零的矩阵。一般地,当非 零元素个数只占矩阵元素总数的25%—30%,或低于这个百分 数时,我们称这样的矩阵为稀疏矩阵。
Loc[i,j]=Loc[0,0]+(n×i+j)*size
其中n为第2维的长度
2019/10/17
12
三维数组A(1..r , 1..m , 1..n)可以看成是r个m×n的 二维数组 ,如下图所示:

数据结构数组和广义表

数据结构数组和广义表

数据结构05数组与广义表数组与广义表可以看做是线性表地扩展,即数组与广义表地数据元素本身也是一种数据结构。

5.1 数组地基本概念5.2 数组地存储结构5.3 矩阵地压缩存储5.4 广义表地基本概念数组是由相同类型地一组数据元素组成地一个有限序列。

其数据元素通常也称为数组元素。

数组地每个数据元素都有一个序号,称为下标。

可以通过数组下标访问数据元素。

数据元素受n(n≥1)个线性关系地约束,每个数据元素在n个线性关系地序号 i1,i2,…,in称为该数据元素地下标,并称该数组为n维数组。

如下图是一个m行,n列地二维数组A矩阵任何一个元素都有两个下标,一个为行号,另一个为列号。

如aij表示第i行j列地数据元素。

数组也是一种线性数据结构,它可以看成是线性表地一种扩充。

一维数组可以看作是一个线性表,二维数组可以看作数据元素是一维数组(或线性表)地线性表,其一行或一列就是一个一维数组地数据元素。

如上例地二维数组既可表示成一个行向量地线性表: A1=(a11,a12,···,a1n)A2=(a21,a22, ···,a2n)A=(A1,A2, ···,Am) ············Am=(am1,am2, ···,amn)也可表示成一个列向量地线性表:B1=(a11,a21,···,am1)B2=(a12,a22, ···,am2)A=(B1,B2, ···,Bm) ············Bn=(a1n,a2n, ···,amn)数组地每个数据元素都与一组唯一地下标值对应。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。




原子的深度为0
空表的深度为1

广义表可以是递归的表,递归表的深度是无穷的,长度是有限的。
一些广义表的例子
(1)A=()——A是一个空表,它的长度为零。 (2)B=(e)——列表B只有一个原子e,B的长度为1。 (3)C=(a,(b,c,d))——列表C的长度为2,两个元素分 别为原子a和子表(b,c,d)。
Ri={<aj1…ji…jn,aj1…ji+1…jn>| 0≤jk≤bk-1, 1≤k≤n 且k≠i,0≤ji≤bi-2, aj1…ji…jn,aj1…ji+1…jn∈D,i=2,…n}
基本操作: InitArray(&A,n,bound1,…,boundn) DestroyArray(&A) Value(A,&e,index1,…,indexn) Assign(&A,e,index1,…,indexn) }ADT Array
快速转置算法



方法:按a.data中三元组的次序进行转置,并将 转置后的三元组置入b中恰当的位置。 建立辅助数组num和cpot, num[col]表示矩阵第 col列中非零元的个数, cpot[col]指示第col列 的第一个非零元素在b.data中的恰当位置。 按行扫描矩阵三元组表,根据某项的列号,确定 它转置后的行号,查cpot表,按查到的位置直接 将该项存入转置三元组表中。 转置时间复杂度为 O(nu+tu+nu+tu)=O(nu+tu)。 若矩阵有200列,10000个非零元素,总共需10000 次处理。
5.2 数组的顺序表示




多维数组用一维的存储单元存放需约定次序。 PASCAL和C语言是以行序为主序,FORTRAN以列序为 主序。 给定维数和各维长度,数组的存储空间确定。 二维数组中任一元素aij的存储地址: Loc(i,j)=Loc(0,0)+(b2*i+j)*L n维数组:教材p89 Loc(j1,j2,…,jn)=Loc(0,0,…,0)+ ∑ciji 其中 cn=L, ci-1=bi*ci, 1<i≤n
(3)三元组表稀疏矩阵的转置运算



方法:按照b.data中的三元组的次序,即M的列序, 依次在a.data中找到相应的三元组进行转置。 步骤:从k=1开始依次扫描找寻所有列号为k的项, 将其行号变列号、列号变行号,顺次存于转置矩 阵三元组表。 其时间复杂度为 O ( a.nu* a.tu )。 例:若矩阵有200行,200列,10,000个非零元素, 总共有2,000,000次处理。
表头和表尾
任何一个非空列表其表头可能是原子,也可能是 列表,而其表尾必定为列表。 例如: GetHead(B)=e, GetTail(B)=( ), GetHead(D)=A, GetTail(D)=(B,C ), 由于(B,C)为非空列表,则可继续分解得到: GetHead((B,C))=B, GetTail((B,C))=(C), 值得提醒的是列表()和(())不同。前者为空 表,长度n=0;后者长度n=1,可分解得到其表头、 表尾均为空表()。
]中,三对角矩
阵有3n-2个元素。 k=2*i+j-3
5.3.2 稀疏矩阵
1. 三元组的表示
稀疏矩阵可由表示非零元的三元组及其行列
数唯一确定 t个非零元,t/(m*n)称为稀疏因子 <0.05 用三元组(i,j,aij)存储行和列的位置,及非 零元数值
(1)稀疏矩阵 (Sparse Matrix)
D
A=( ) B=(e) C=(a,(b,c,d)) D=(A,B,C) E=(a,E)
A
B
C
e
a
b
c
d
(2)列表可为其它必列出子表的值,而是通过子表的名 称来引用。 D=(A,B,C)
(3)列表可以是一个递归的表,即列表也可以是其 本身的一个子表。 例如列表E就是一个递归的表。 E=(a,E)
(4)D=(A,B,C)——列表D的长度为3,三个元素都是列表。 显然,将子表的值代入后,则有 D=((),(e),(a,(b,c,d)))。
(5)E=(a,E)——这是一个递归的表,它的长度为2。E相当 于一个无限的列表E=(a,(a,(a,…)))。
列表的三个重要结论
(1)列表的元素可以是子表,而子表的元素还可以 是子表,…。由此,列表是一个多层次的结构,可 以用图形象地表示。 例如下图表示的是列表D。图中以圆圈表示列表, 以方块表示原子。
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) { 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]; } } return OK; }
0 稀疏矩阵 0 0 A 67 0 91 0
0 11 0 0 0 0 0 11 0 0 0 17 0
0 0 0 0 0 28 0 0 0 6 0 0 0
22 0 6 0 0 0 0 0 0 0 0 39 0
0 0 0 0 0 0 91 0 0 0 0 0 0
第五章 数组和广义表
数组




一维数组具有线性表的结构,一般不进行插入和删除操 作,只定义给定下标读取元素和修改元素操作 二维数组每个数据元素对应一对数组下标,在行方向上 和列方向上都存在一个线性关系,即存在两个前驱和两 个后继。也可看作是以线性表为数据元素的线性表。 n维数组每个数据元素对应n个下标,受n个关系的制约, 其中任一个关系都是线性关系。 因此,多维数组是对线性表的扩展:线性表中的数据元 素本身又是一个多层次的线性表。
稀疏矩阵的转置
(算法5.1)
Status TransposeSMatrix(TSMatrix M,TSMatrix &T) { int q,col,p; T.mu=M.nu; T.nu=M.mu; T.tu=M.tu; if (T.tu) { q=1; for(col=1;col<=M.nu;++col) for(p=1;p<=M.tu;++p) if(M.data[p].j==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; ++q; } } return OK; }
col
1 2 3 4 5 6 7
语 义
num 2 2 2 1 0 1 0 矩阵 A 各列非 [col] 零元素个数 cpot 1 3 5 7 8 8 9 矩阵 B 各行开 [col] 始存放位置

cpot[1]=1 cpot[col]=cpot[col-1]+num[col-1]
稀疏矩阵的快速转置(算法5.2)


aij=aji
1≤i,j≤n
压缩存储方法:为每一对对称元分配一个存储空间
将下三角的元素,按行存储到一维数组sa中 共有n(n+1)/2个存储单元, aij在一维数组中的位置k为:i(i-1)/2+j-1 当i>=j 否则 j(j-1)/2+i-1

三角矩阵:上(下)三角中的元均为常数c或0
2. 十字链表



当矩阵中非零元素的个数和位置经过运算后 变化较大时,就不宜采用顺序存储结构,而 应采用链式存储结构来表示三元组。 稀疏矩阵的链接表示采用十字链表:行链表 与列链表十字交叉。 行链表与列链表都是带表头结点的循环链表。 用表头结点表征是第几行,第几列。
十字链表(链式存储)
3 0 0 5 0 -1 0 0 2 0 0 0
0 0 0 0 91 0 15 11 0 0 0 17 0 0 0 6 0 0 0 0 0 0 0 39 0 0 0 0 0 0 0 0 28 0 0 0 0 0 0 22 0 0
A 67
行数m = 6, 列数n = 7, 非零元素个数t = 6
求下列广义表操作的结果:
① GetHead((p,h,w));
② GetTail((b,k,p,h));
③ GetHead (((a,b),(c,d))); ④ GetTail(((a,b),(c,d))); ⑤ GetHead (GetTail (((a,b),(c,d)))); ⑥ GetTail (GetHead (((a,b),(c,d))));
[0] [1] [2] [3] [4] [5] [6] [7]
[0] [1] [2] [3] [4] [5] [6] [7]
(2) 三元组顺序表
#define MAXSIZE 12500 //非零元个数最大值 typedef struct { int i, j; //行下标和列下标 ElemType e; } Triple; typedef struct{ Triple data[MAXSIZE+1]; //非零元三元组表 int mu,nu,tu; //行数、列数、非零元个数 }TSMatrix; TSMatrix a,b; 所需空间:3*tu+3
相关文档
最新文档