收藏 分享(赏)

第五章+数组和广义表.ppt

上传人:11xg27ws 文档编号:4725792 上传时间:2019-01-09 格式:PPT 页数:75 大小:699.50KB
下载 相关 举报
第五章+数组和广义表.ppt_第1页
第1页 / 共75页
第五章+数组和广义表.ppt_第2页
第2页 / 共75页
第五章+数组和广义表.ppt_第3页
第3页 / 共75页
第五章+数组和广义表.ppt_第4页
第4页 / 共75页
第五章+数组和广义表.ppt_第5页
第5页 / 共75页
点击查看更多>>
资源描述

1、第五章 数组和广义表,学习目标: 理解数组类型的特点及其在高级编程语言中的存储表示和实现方法,并掌握数组在“以行为主”的存储表示中的地址计算方法。掌握特殊矩阵的存储压缩表示方法。 理解稀疏矩阵的两类存储压缩方法的特点及其适用范围,领会以三元组表示稀疏矩阵时进行矩阵运算所采用的处理方法。,5.1 数组的类型定义,5.3 特殊矩阵的压缩存储,5.2 数组的顺序存储和实现,5.4 广义表,5.1 数组的定义和运算,数组是一种数据类型。从逻辑结构上看,数组可以看成是一般线性表的扩充。二维数组可以看成是线性表的线性表。例如:,我们可以把二维数组看成一个线性表:A=( 1 2 j n),其中j(1j n)

2、本身也是一个线性表,称为列向量。,矩阵Amn看成n个列向量的线性表,即j=(a1j,a2j, ,amj),还可以将数组Amn看成另外一个线性表:B=(1,,2,, i ,,m),其中i(1im)本身也是一个线性表,称为行向量,即:i= (ai1,ai2, ,aij ,ain)。,看一个二维数组的简单情况。 D=aij|0ib1-1,0jb2-1, aij ElemType R=ROW,COL 其中: ROW=|i=1,b1-1, 0jb2-1, ai-1j , aij ElemType (称作“行关系“) COL=|j=1,b2-1, 0ib1 -1, ai j-1 ,aij ElemType

3、 (称作“列关系“),数组的抽象类型定义,ADT Array 数据对象:Daj1j2.jijn| aj1jnESet,0ji bi-1, i=1,.,n ji是第i维下标, bi为数组第i维的长度 数据关系:RR1, R2, ., RnRi= | 0 jk bk-1, 1 k n 且k i, 0 ji bi-2, aj1. ji. jn , aj1.ji+1.jn ESet i=2,.,n ADT Array,基本操作:,InitArray(&A, n, b1, ., bn) 构造n维数组A,基本操作:,DestroyArray(&A) 撤销数组A。,Value(A,&e, index1, .

4、, indexn) 初始条件: n维数组A存在, 有n 个下标值。 操作结果: 若各下标不超界返回A的对应元素值。,Assign(&A, e, index1, ., indexn) 初始条件: n维数组A和值e存在, 有n个下标值。 操作结果:若下标不超界, 将e值赋给A的对应元素。,实际上数组是一组有固定个数的元素的集合。由于这个性质,使得对数组的操作不象对线性表的操作那样,可以在表中任意一个合法的位置插入或删除一个元素。对于数组的操作一般只有两类: (1)获得特定位置的元素值; (2)修改特定位置的元素值。,5.2 数组的顺序表示和实现,数组维数及各维长度一旦给定,则该数组中元素的个数是固

5、定的,所以不可以对数组做插入和删除操作,不涉及移动元素操作,因此对于数组而言,采用顺序存储法比较合适。,如二维数组有两种顺序映象的方式: 以行序为主序(低下标优先,高下标为主序) a11 ,a12, a1n ,a21 ,a22 ,a2n , ,a1 ,am2 , , amn 2) 以列序为主序(高下标优先,低下标为主序) a11,a21,am1 ,a12 ,a22 , ,am2 ,a1n ,a2n , ,amn,例如:A(2,3,2),以行序为主序(0,0,0)( 0,0,1 ) ( 0,1,0 )( 0,1,1 ) ( 0,2,0 )( 0,2,1 ) (1,0,0) (1,0,1)(1,1

6、,0)(1,1,1) (1,2,0)(1,2,1),以列序为主序(0,0,0) (1,0,0) (0,1,0) (1,1,0) (0,2,0) (1,2,0) (0,0,1) (1,0,1) (0,1,1) (1,1,1) (0,2,1) (1,2,1),行向量 下标 i 页向量 下标 i 列向量 下标 j 行向量 下标 j列向量 下标 k 二维数组 三维数组,A546以行序为主存储,计算A322 的地址,三维数组a223的存储映象, 起始下标0,例如:,a0,0,1,a0,0,0,a0,0,2,a0,1,0,a0,1,1,a0,1,2,a1,0,1,a1,0,0,a1,0,2,a1,1,0,

7、a1,1,1,a1,1,2,基地址或基址,三维数组A中任一元素ai,j,k 的存储位置Loc(ai,j,k)=Loc(a0,0,0)+(b2*b3* i+b3* j+k)*,L,a0,0,1,a0,0,0,a0,0,2,a0,1,0,a0,1,1,a0,1,2,a1,0,1,a1,0,0,a1,0,2,a1,1,0,a1,1,1,a1,1,2,二维数组A中任一元素ai,j 的存储位置:Loc(ai,j)=Loc(a0,0)+(b2* i+ j)*三维数组,L,基地址或基址,数组元素的存储位置是其下标的线性函数,由于计算各个元素存储位置的时间相等,所以存储数组中任一元素的时间也相等,称具有这一特

8、点的存储结构为随机存储结构。,推广到一般情况,可得到 n 维数组数据元素存储位置的映象关系,n维数组元素存储地址的计算公式设各维长度分别为b1, b2, b3, , bn,每个元素占L个存储单元,起始地址是LOC(0,0,0) ,求元素 的存储位置?,(Cn=L,ci-1=bi*ci,1in),LOC (j1,j2,jn ) = LOC(0,0,0) + (b2*b3*bn * j1+ b3*b4*bn * j2+ + bn*jn-1 + jn ) * L,N维数组数据元素存储地址计算,1、数组M110-1603,起始地址是1000,每个元素占3个存储单元,数组元素个数是 ,M242的地址是

9、。 2、数组A0 81 10的成员由6个字节组成,存放a要 个字节,a的第8行第5列占 个字节。按行序a85与按列序 起始地址相同。,(10-1+1)*(6-(-1)+1)*(3-0+1)=320 LOC(M242)=1000+(i-1)*b2*b3+(j-(-1)*b3+k*l =1000+32*(2-1)+4*(4+1)+2*3=1162,LOC(a85)=a(起始地址)+(i*b2+(j-1))*l =a+(8*10+4)*6=a+504, LOC(a310)=a(起始地址)+ (j-1)*b1+i)*l=a+(9*9+3)*6=a+504。,计算二维数组元素地址的通式 设一般的二维数组

10、是Ac1d1, c2d2,这里c1,c2不一定是0。,二维数组列优先存储的通式为: LOC(aij)=LOC(ac1,c2)+(j-c2)*b1+i-c1*L,单个元素长度,aij之前的行数,数组基址,总列数,即第2维长度,aij本行前面的元素个数,则行优先存储时的地址公式为: LOC(aij)=LOC(ac1,c2)+(i-c1)*b2+j-c2*L,/-数组的顺序存储表示- typedef struct ElemType *base ; /存储空间基址int dim ; /数组维数int *bounds ; /数组维界基址int *constants ;/数组映象函数常量基址 Array

11、/-基本操作原型说明-,A456的初始化,数组的初始化: Status InitArray(Array ,5.3 矩阵的压缩存储,压缩存储:为多个值相同的元素只分配一个存储空间,对零元素不分配空间。 目的:节省存储空间 任务:压缩存储矩阵并使矩阵的运算有效进行。 矩阵的存储:二维数组 可压缩存储的矩阵有两类: 特殊矩阵:值相同的元素或零元素在矩阵中分布有一定规律。如三角矩阵、对角矩阵。随机稀疏矩阵:值相同的元素或零元素在矩阵中分布没有一定规律。,5.3.1 特殊矩阵,三类特殊矩阵: 对称矩阵:若 n 阶方阵A中的元满足特性 aij =aji 1i,jn 则称为 n 阶对称矩阵;2. 三角矩阵:

12、若 n 阶方阵中下(上)三角(不包括对角线)中的元均为常量 c 或 0,则称为上(下)三角矩阵;3. 对角矩阵:若n阶方阵中的非零值元都集中在以主对角线为中心的(由k条对角线组成的)带状区域中,则称为k对角矩阵。,5.3.1 特殊矩阵对称矩阵,对称矩阵 n阶矩阵A中元素满足性质aij=aji (1i,jn)。 压缩存储: 为每一对对称元素分配一个存储空间. n(n+1)/2 用行主序的上、下三角阵来存储对称矩阵的元素。 sak(0kn(n+1)/2-1) 为对称矩阵的压缩存储结构,5.3.1 特殊矩阵上(下)三角阵,上(下)三角阵:矩阵下(上)三角(不含对角线)元素为常数c或0的n阶矩阵。 压

13、缩存储: 存储上(下)三角中的元素和常数c。 n(n+1)/2+1 用行主序存储上(下)三角阵的元素。 sak(0kn(n+1)/2) 为上(下)三角阵的压缩存储结构,5.3.1 特殊矩阵对角矩阵,对角矩阵:所有非零元素都集中在以主对角线为中心的带状区域。其他元素为0。 用行主序存储对角阵的元素。4+3*(n-2) sak(0k4+3*(n-2) 为对角阵的压缩存储结构,不在第一行的非零元ai,j,它前面已经存储了前i-1行元素为2+3(i-2) 若ai,j是本行需第1个存储的元素(ai,i-1),k=3(i-1)-1,(j=i-1) 若ai,j是本行需第2个存储的元素(ai,i) ,k=3(

14、i-1),(i=j) 若ai,j是本行需第3个存储的元素(ai,i+1) ,k=3(i-1)+1,(j=i+1) 三式合并有k=2(i-1)+j-1。,特殊矩阵习题,1 设5对角矩阵A=(ai,j)20*20(i,j从1开始)以行主序存放。按特殊矩阵压缩存储的方式将其5条对角线上的元素存入B-10:m中,计算元素A1515的存储位置。2 将一个A11001100的三对角矩阵按行优先存于一维数组B1298中,A6665在B中的位置为 。,解1:5对角阵A=(aij)20*20第一行和第20行分别有3个元素,第二行和第19行有4个元素,其余各行分别有5个元素,A1515是第(3+4+5*12+3)

15、70个元素,存储位置70-10-1=59,解2:LOC(A6665)=2*(i-1)+j=2*65+65=195,假设 m 行 n 列的矩阵含 t 个非零元素,则称为稀疏因子。 通常认为 0.05 的矩阵为稀疏矩阵。,5.3.2 稀疏矩阵的压缩存储,何谓稀疏矩阵?,若以二维数组直接存储稀疏矩阵,产生问题:,1) 浪费空间, 零值元素占了很大空间;,2) 浪费时间, 进行了很多和零值有关的无谓运算,遇除法,还需判别除数是否为零。,1) 尽可能少存或不存零值元素;,解决问题的原则:,2) 尽可能减少没有实际意义的运算;,3) 操作方便。即:能尽可能快地找到与下标值i, j对应的元素;能尽可能快地找

16、到同一行或同一列的非零值元素。,稀疏矩阵的压缩存储方法:,一、三元组顺序表,二、 十字链表,稀疏矩阵的压缩存储,要同时存储非零元素的值和该元素在矩阵中所处的行列号,可用结构体数组来存储,每个非零元存储在一个结构体中。称之为稀疏矩阵的三元组顺序表表示法,简称三元组法。每个非零元的表示形式如图所示:,一、三元组顺序表,#define MAXSIZE 1000 /非零元的最大数 typedef struct int i,j; /非零元的行下标和列下标ElemType e; /非零元素的值 Triple;typedef struct Triple dataMAXSIZE+1; /三元组表 data0未

17、用int mu,nu,tu; /行数、列数和非零元个数 TSMatrix;,三元组顺序表的类型定义,Amn,1 2 14,2 2 -7,3 1 36,3 4 28,1 5 -5,三元组顺序表又称有序的双下标法,它的特点是,非零元在表中按行序有序存储,因此便于进行依行顺序处理的矩阵运算。,如何求转置矩阵?,Amn,Bnm,B仍以行为主序存储在三元组中,转置用常规的二维数组表示时的算法,其时间复杂度为: O(munu),for(c=1;c=nu;c+)for(r=1;r=mu;r+)Bcr=Arc;,用“三元组“实现方法1:如 p 98,2 1 14,5 1 -5,2 2 -7,1 3 36,4

18、3 28,void TransMatrix(TSMatrix A, TSMatrix * B) /把矩阵A转置到B所指向的矩阵中去。int q, p, col ;B-mu= A.nu ; B-nu= A.mu ; B-tu= A.tu ;if(B-tu0) q=1;for(col=1; coldataq.i=A.datap.jB-dataq.j=A.datap.i;B-dataq.e=A.datap.e; q+; ,其时间复杂度为: O(munu2 ) tu*n非零元个数*列数,用“三元组”实现转置方法2(快速转置):一趟将所有的元素直接到位,1 3 36,2 1 14,2 2 -7,5 1

19、-5,4 3 28,for(c=1;c=A.nu;c+) numc=0; for(t=1;t=A.tu;t+)numA.datat.c+; /A每列非零元个数,增设向量num和pos表示B各行非零元个数和每行第一个非零元在三元组中的位置。,/B每行非零元个数,pos1= 1; for(col=2;coldata的位置poscol=poscol-1+ numcol-1;,1 2 4 4 5,1 2 0 1 1,FastTrans(TSMatrix *B,TSMatix A); B-mu=A.nu; B-nu=A.mu; B-tu=A.tu;if(B-tu!=0) for(col=1;cold的位

20、置for(col=2;coldataq.i=A.datap.j;B-dataq.j=A.datap.i;B-dataq.e=A.datap.e;poscol+; ,分析算法FastTr的时间复杂度:,时间复杂度为: O(A.nu+A.tu)O(m*n),for(col=1;col=A.nu;col+) for(t=1;t=A.tu;t+) for(col=2;col=A.nu;col+) for(p=1;p=A.tu;p+),精典算法: for(i=1;i=m1;i+)for(j=1;j=n2;j+) Cij= 0;for(k=1;k=n1;k+)Cij+=Aik*Bkj;,其时间复杂度为:

21、O(m1n1n2),矩阵相乘,增设辅助向量pos和ctemp,pos表示B矩阵各行第一个非零元在B.data中的位置,ctemp用来计算并临时存储C的当前行。例如:,经典算法中,不论Ai,k,Bk,j是否为零,都要进行一次乘法运算。用三元组表来实现时,只对矩阵的非零元操作, 矩阵的零元素都自动跳过。稀疏矩阵相乘(CAB),可按行对A进行乘法; 用三元组A中i行首个非零元(i,k,Aik), 和三元组B中所有行号为k的对应元素(k,j,Bkj)相乘,将结果存放到C的i行各j列; 再用A第i行下一个非零元(i,t,Ait)和B所有行号t的对应元素(t,j,Btj)相乘,结果累加到C的i行各j列,直

22、到A的i行处理完得出C的i行结果。然后再以A中其它行元素为准,与B依次相乘求出C的各行。,3 0 1 5 0 -1 0 0 2 0 0 0,0 21 0 -2 40 -1,-2 5 -1 00 4,A= B= C=,cc 1 2ctemp 0 0,6,-2,10,5,以C的第一行为例,1 2 35,1 1 -2 1 2 5,2 1 -1 3 2 4,再算出C的其它行,MultS(TSMatrix A,TSMatrix B,TSMatrix *C) C=AB if(A.n*B.m !=0) (根据B求pos);C-mu=A.mu; C-nu=B.nu; C-tu=0; p=1; while(pn

23、u;k+)ctempk=0; /累加器各元素清零while(pdata中); ,for(t=1;td的位置 for(t=2;t=B.mu+1;t+)post=post-1+numt-1;,while(p=A.tu ,for(cc=1;cctu+;C-dataC-tu=(cr,cc,ctempcc); ,3 0 1 5 0 -1 0 0 2 0 0 0,0 21 0 -2 40 -1,-2 5 -1 00 4,A= B= C=,cc 1 2ctemp 0 0,6,-2,10,5, br=A.dp.c; for(q=posbr;qposbr+1;q+) cc= B.dq.c; /表示乘积元素在C中

24、的列号ctempcc+=A.dp.e*B.dq.e ;p+; ,1 2 35,1 1 -2 1 2 5,2 1 -1 3 2 4,行逻辑链接的顺序表,typedef struct triple dataMAXSIZE+1;int rposMARC+1;int mu,nu,tu;RLSMatrix;,分析上述算法的时间复杂度,累加器ctemp初始化的时间复杂度:O(A.muB.nu) 求c所有非零元的时间复杂度:O(A.tuB.tu/B.mu) 进行压缩存储的时间复杂度:O(A.muB.nu) 总的时间复杂度就是:O(A.muB.nu+A.tuB.tu/B.mu),若A是m行n列的稀疏矩阵,B是

25、n行p列的稀疏矩阵, 则A中非零元的个数 A.tu = amn,B中非零元的个数 B.tu = bnp, 相乘算法的时间复杂度就是 O(mp(1+nab) , 当a0.05 和b0.05及 n1000时,(nab1) 相乘算法的时间复杂度就相当于 O(mp)。,三元组顺序表非零元在表中按行序有序存储, 因此, 便于进行依行顺序处理的矩阵运算。但不符合解决问题的原则 3) 操作方便。即:能尽可能快地找到与下标值i,j对应的元素;尽可能快地找到同一行或同一列的非零元素。若需随机存取某一行或某一列中的非零元,则需从头开始进行查找。要想方便的随机存取某行某列的非零元, 则应采用十字链表。,二、 十字链

26、表矩阵的每个非零元用一个结点表示,该结点含row, col, value和right, down。分别表示该非零元的行、列、值和链接同行、同列非零元的指针。,简写:,整个矩阵用一个头结点表示,该结点含稀疏矩阵的行数、列数、非零元素的个数和指向行、列链表头的指针数组。,typedef struct OLNode int r,c; /非零元素的行和列下标ElementType e;/非零元素所在行表列表的后继链域struct OLNode * rp,*dp; OLNode; *OLink;typedef struct OLink * rhead,*chead; /行、列链表头指针向量int m,n

27、,len; /行数、列数、非零元素的个数CrossList;,十字链表的结构类型说明如下:,三、 十字链表,M,十字链表的生成算法 稀疏矩阵M采用十字链表存储的生成算法如下:,Status CreateSMatrix_OL (CrossList / 生成新结点if (M.rheadi= =null M.rheadi -j j) /行表空直接插入p-right = M.rheadi; M.rheadi = p; /新点列号小插在前面,十字链表的生成算法 稀疏矩阵M采用十字链表存储的生成算法如下:,else (寻找新结点在行表中的列位置) / 新结点列号大且当前结点不是最后一个结点查找列位置for

28、(q = M.rheadi;(q-right ) 其时间为O(t*s)。因为,共有t个非零元素。S=maxm,n此为在 行或列中查找元素插入位置花费的时间。,3 0 0 5 0 -1 0 0 2 0 0 0,课后思考: 1、稀疏矩阵采用十字链表存储的生成算法 2、利用十字链表如何实现两个矩阵的相加,5.4 广义表 5.4.1 广义表的类型定义,广义表是线性表的推广。广义表是n个数据元素(d1,d2,d3,dn)的有限序列,广义表中的di既可以是单个元素,还可以是一个广义表,由此可见,广义表的定义是递归定义的。,其中:di 称为 LS 的单元素(原子)或子表。,LS=(d1,d2,d3,dn),

29、例如: A = ( ) B = (e)C = (a,(b,c,d) D = (A, B, C)E = (a, E) = (a, (a, (a, , ) ) ),广义表的类型定义,ADT Lists 数据对象:D di | i=1,2,n; n0,且diD0或 diLists D0为某个数据对象数据关系:LR| di-1 ,diD, 2in ADT Lists,基本操作:,广义表是一个多层次结构,例如:,D=(E, F),其中:E=(a, (b, c)F=(d, (e),D,E,F,a,( ),d,( ),b,c,e,广义表 LS = ( 1, 2, , n )的结构特点:,1) 广义表中的数据

30、元素有相对次序; 2) 广义表长度定义为最外层包含元素个数;,3) 广义表的深度定义为所含括弧的重数;注意: “原子”的深度为 0,空表”的深度为 1,4) 广义表可以共享;,5) 广义表可以是一个递归的表。递归表的深度是无穷值,长度是有限值。,6) 非空广义表 LS = ( 1, 2, , n) 均可分解为表头 Head(LS) = 1 和表尾 Tail(LS) = ( 2, , n) 两部分。,例如: D = ( E, F ) = (a, (b, c),F ),Head( D ) = E Tail( D ) = ( F ),Head( E ) = a Tail( E ) = ( ( b,

31、c) ),Head( ( b, c) ) = ( b, c) Tail( ( b, c) ) = ( ),Head( ( b, c) ) = b Tail( ( b, c) ) = ( c ),Head( ( c ) ) = c Tail( ( c ) ) = ( ), 创建、销毁和复制DestroyGList(,基本操作, 求长度、深度、表头、表尾Length(L); Depth(L); GetHead(L); GetTail(L);, 遍历Traverse_GL(L, Visit();,5.4.2 广义表的存储结构,用链表,每个元素用一个结点表示,结点分为两种结构:表结点和原子结点, 用共

32、用体表示。,表结点: 原子结点:,typedef enum ATOM, LIST ElemTag; /标志类型 typedef struct GLNode ElemTag tag; /标志域区别原子结点和表结点union /原子结点值表结点指针htp组成共用体域 AtomType atom; /atomstruct struct GLNode *hp,*tp;htp; ; *GList;,1) 表头、表尾分析法:,构造存储结构的两种分析方法:,若表头为原子,则用原子结点:,空表 L=NULL ( L为头指针 ),非空表 L,指向表头,指向表尾,否则用表结点;表尾总是用表结点或空; 子表结构依次

33、类推。,例如:,L=(a, (x, y), (x),注意:表尾是表去掉表头的剩余部分,L = ( a, ( x, y ), ( ( x ) ) ),a,( ),( ),L = ( ),( ),x,x,y,可共享,例如: A = ( ) B = (e) C = (a,(b,c,d)D = (A, B, C)E = (a, E) = (a, (a, (a, , ) ) ),A=NULL,2) 子表分析法:,若子表为原子,则为,空表 ls=NIL,非空表,指向子表1,否则,依次类推。,指向子表2,指向子表n,L=NULL,L = ( a, ( x, y ), ( ( x ) ) ),a,( x, y

34、 ),( ( x ) ),L = ( ),可共享,例如:,两种分析方法的结果相同,每对括号对应一个空指针不对应一个表结点,表结点: 原子结点:,也可采用另一种结点结构的链表,typedef enum ATOM,LIST ElemTag; typedef struct GLNode ElemTag tag; union /值域atom和表头指针域hp的共用体域 AtomType atom; struct GLNode * hp; ; struct GLNode * tp; *GList;,L = ( a, ( x, y ), ( ( x ) ) ),a,( ),( ),L = ( ),( ),x,x,y,每对括号对应一个表结点,完全相同才可共享!,( ),( ( ) ),( ( a ),( ) ),每对括号对应一个表结点,1.了解数组的两种存储表示方法,并掌握数组在以行为主的存储结构中的地址计算方法。 2.掌握对特殊矩阵进行压缩存储时的下标变换公式。 3.了解稀疏矩阵的两类压缩存储方法的特点和适用范围,领会以三元组表示稀疏矩阵时进行矩阵运算采用的处理方法。,4. 掌握广义表的结构特点及其存储表示方法,掌握任意一种结构的链表,学会对非空广义表进行分解的两种分析方法:表头-表尾分析法或子表分析法。,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 实用文档 > 统计图表

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报