收藏 分享(赏)

数据结构详解.ppt

上传人:Facebook 文档编号:3425604 上传时间:2018-10-27 格式:PPT 页数:60 大小:504KB
下载 相关 举报
数据结构详解.ppt_第1页
第1页 / 共60页
数据结构详解.ppt_第2页
第2页 / 共60页
数据结构详解.ppt_第3页
第3页 / 共60页
数据结构详解.ppt_第4页
第4页 / 共60页
数据结构详解.ppt_第5页
第5页 / 共60页
点击查看更多>>
资源描述

1、第5章 数组和广义表,5.1数组的定义 5.2数组的顺序表示和实现 5.3矩阵的压缩存储 54广义表 5.5广义表的存储结构,5.1数组的定义,说明: A是数组的名字 A是一个n维数组,共有 bi个元素 bi是第i维的长度,称为维界,表示该维的下标变化为0bi -1 每一个数组元素的类型都是int 除第一个元素外,每个元素都有一个直接前驱 除最后一个元素外,每个元素都有一个直接后继,在C中定义: int Ab1b2bn;,因此,可以把数组看成是一个定长的线性表,表中每个元素也是一个定长的线性表,.,数组的ADT ADT Array 数据对象: D=aj1 j2.jn|n(0)称为数组的维数,b

2、i是数组的第i维的长度ji是数组元素的第i维下标,ji=0, bi-1 , 1in aj1 j2.jnElemSet数据关系:R=R1,R2,.,RnRi= |0jkbk-1, 1kn 且ki,0jibi-2, aj1ji.jn,aj1ji+1.jnD, i=1,2,n,基本操作:InitArray (&A, n, bound1, , boundn)操作结果:若维数n和各维长度合法,则构造相应的数组A,并返回OK。DestroyArray(&A)操作结果:销毁数组A。 Value(A,&e, index1, , indexn)初始条件:A是n维数组,e为元素变量,随后是n个下标值。操作结果:若

3、各下标不超界,则e赋值为指定的A的元素值,并返回OK。 Assign(&A, e, index1, , indexn)初始条件:A是n维数组,e为元素变量,随后是n个下标值。操作结果:若各下标不超界,则将e的值赋给指定的A的元素,并返回OK。 ADT Array,5.2数组的顺序表示和实现,行序:越是后面的下标变化越快 列序:越是前面的下标变化越快 数组一旦定义,可由下标知道任意元素的位置,一维:Loci=Loc0+i*h /h为每个元素占用的存储单元长度,0 1 2 3 4 5 6 7 8 9,二维:Loci,j=Loc0,0+(b2*i+j)*h,三维:Loci,j,k=Loc0,0,0+

4、(b2*b3*i+b3*j+k)*h,下标 i 下标 i 下标 j 下标 j下标 k,n维: Locj1,j2,.,jn=Loc0,0,0+(b2*b3*bn*j1+b3*b4*bn*j2+.+bn*jn-1+jn)*h,令C1=b2*b3*bn*hC2=b3*b4*.*bn*hCn-1=bn*hCn=h,Locj1,j2,.jn=Loc0,0,0+ji*Ci,Ci=Ci+1*bi+1,#include typedef void *va_list; void va_start(va_list argptr, last_parm) /最后一个固定参数为last_parm /argptr指向变长参

5、数表中的第一个参数 void va_end(va_list argptr) type va_arg(va_list argptr, type) / 返回argptr指向的type类型的参数, /argptr指向下一个参数 /printf(*format,),/- - - - -数组的顺序存储表示- - - - - #include /标准头文件,提供宏va_start、va_arg和va_end/ 用于存取变长参数表 #define MAX_ARRAY_DIM 8 /假设数组维数的最大值为8 typedef struct ElemType *base; /数组元素基址,由InitArray分配

6、int dim /数组维数int *bounds; /数组维界基址, 由InitArray分配,biint *constants /数组映象函数常量基址,由InitArray分配,ci Array;,/- - - - -基本操作函数原型说明- - - - - Status InitArray(Array /A是n维数组,e为元素变量,随后是n个下标值。/若各下标不超界,则将e的值赋给指定的A的元素,并返回OK。,/- - - - -基本操作的算法描述- - - - - Status InitArray(Array ,1.获得dim,2.申请空间存放bi的值,4.计算数组元素个数elemtota

7、l,3.获得bi的值,5.申请空间存放A中所有元素的值,6.申请空间存放Ci的值,存放bi ci的值 给A分配存储空间,/- - - - -基本操作的算法描述- - - - - Status InitArray(Array ,A.base=(ElemType*)malloc(elemtotal*sizeof(ElemType);if (!A.base) exit(OVERFLOW);/求映象函数的常数Ci, A.constantsi-1,i=1,dimA.constants=(int *)malloc(dim * sizeof(int);if (!A.constants) exit(OVERF

8、LOW);A.constantsdim-1=1; / h=1,指针的增减以元素的大小为单位for(i=dim-2; i=0; - -i )A.constantsi= A.boundsi+1* A.constantsi+1;return OK; ,Status DestroyArray(Array ,Status Locate(Array A, va_list ap, int ,Status Value(Array A, ElemType ,Status Assign(Array ,5.3 矩阵的压缩存储,一、特殊矩阵 1对称矩阵n阶矩阵满足:aij=aji,a11 a12 a13 a14 a1

9、5 a16 a21 a22 a23 a24 a25 a26 a31 a32 a33 a34 a35 a36a41 a42 a43 a44 a45 a46 a51 a52 a53 a54 a55 a56a61 a62 a63 a64 a65 a66,可将n2个矩阵元素压缩存储到n(n+1)/2个存储单元中且a1n2与sa1n(n+1)/2的对应关系为:aij对应sak,a11 a21 a22 a31 a32 a33 a41 a42 a43 a44 a51 a52 a53 a54 a55 a61 a62 a63 a64 a65 a66,称sa1n(n+1)/2为a1n2的压缩矩阵,压缩矩阵,a11

10、 a21 a22 a31 a32 a33 a41 a42 a43 a44 a51 a52 a53 a54 a55 a61 a62 a63 a64 a65 a66,2对角矩阵,带宽为2b+1的带状矩阵 当0i,jn-1 且 |i-j|b时 ai,j=0 带状区域中共有(2b+1)n-b(b+1)个元素,存储方法: 除去第一行和最后一行,每行都存放2b+1个元素整个带状矩阵放在(2b+1)n-2b个单元中,增补了b(b-1)个元素,增补的方法是以对角线为中心,左右各b个元素,不足补齐Loc(aii)=Loc(ai-1i-1)+(2b+1)h=Loc(a00)+(2b+1)*i*hLoc(aij)=

11、Loc(aii)+(j-i)*h=Loc(a00)+(2bi+j)h,1,1 1,2 1,3 2,1 2,2 2,3 2,4 3,1 3,2 3,3 3,4 3,54,2 4,3 4,4 4,5 4,65,3 5,4 5,5 5,66,4 6,5 6,6,1,1 1,2 1,3 2,1 2,2 2,3 2,4 3,1 3,2 3,3 3,4 3,5 4,2 4,3 4,4 4,5 4,6 5,3 5,4 5,5 5,6 6,4 6,5 6,6,非零元比零元少,且分布没有规律 =t/(m*n)0.05,二、稀疏矩阵 (Sparse Matrix),行数m = 6, 列数n = 7, 非零元素个数

12、t = 6,1稀疏矩阵的ADT ADT SpareMatrix 数据对象:D=ai j|i=1,2,m;j=1,2,n;ai,jElemSet,m和n分别称为矩阵的行数和列数数据关系:R=Row,ColRow=|1im, 1jn-1Col= |1im-1, 1jn基本操作:CreateSMatrix(初始条件:稀疏矩阵M存在。操作结果:销毁稀疏矩阵M。,PrintSMatrix(M);初始条件:稀疏矩阵M存在。操作结果:输出稀疏矩阵M。CopySMatrix(M, 初始条件:稀疏矩阵M与N的行数和列数对应相等。操作结果:求稀疏矩阵的差Q=M-N。,MulSMatrix(M, N, 初始条件:稀

13、疏矩阵M存在。操作结果:求稀疏矩阵M的转置疏矩T。 ADT SparseMatrix,2稀疏矩阵的压缩存储用一个三元组(i,j,aij)表示矩阵中的一个非零元再加上m和n就可以唯一的确定一个稀疏矩阵,三元组表 (1, 2,12), ( 1, 3, 9),( 3, 1,-3),( 3, 6,14), ( 4, 3,24),( 5, 2,18),( 6, 1,15), ( 6, 4,-7),稀疏矩阵,(1)三元组顺序表用顺序结构表示三元组,以行序为主序 /- - - - -稀疏矩阵的三元组顺序表存储表示- - - - - #define MAXSIZE 12500 /假设非零元素个数的最大值为12

14、500 typedef struct int i, j; /该非零元素的行下标和列下标ElemType e; Triple; typedef struct Triple dataMAXSIZE+1; /非零元素三元组表,data0未用int mu, nu, tu; /矩阵的行数、列数和非零元素个数 TSMatrix;,( (1,3,-3), (1,6,15), (2,1,12), (2,5,18), (3,1,9), (3,4,24), (4,6,-7), (6,3,14),三元组表 (1, 2,12), ( 1, 3, 9),(3, 1,-3),(3, 6,14), ( 4, 3,24),(

15、5, 2,18),(6, 1,15), ( 6, 4,-7),Status TransposeSMatrix(TSMatrix M, TSMatrix /TransposeMatrix,应确切知道转置前每一列的第一个非零元在T中的位置 用numcol表示M中第col列中非零元的个数cpotcol表示M中第col列的第一个非零元在T的位置,按三元组的顺序进行转置,col 1 2 3 4 5 6 7 numcol 2 2 2 1 0 1 0 cpotcol 1 3 5 7 8 8 9,( (1,3,-3), (1,6,15), (2,1,12), (2,5,18), (3,1,9), (3,4,2

16、4), (4,6,-7), (6,3,14),(1, 2,12), ( 1, 3, 9),( 3, 1,-3),( 3, 6,14), ( 4, 3,24),( 5, 2,18),( 6, 1,15), ( 6, 4,-7),Status FastTransposeSMatrix(TSMatrix M,TSMatrix /FastTransposeMatrix,(2)行逻辑链接的顺序表 两个矩阵相乘的一般方法:for(i=1; i=m1; +i )for(j=1;j=n2;+j) Qij=0;for(k=1;k=n1;+k) Qij+=Mik*Nkj;,若M和N都是稀疏矩阵,则Mik和Nkj中

17、有一个是零,就不用相乘, 因此,实际是M中的三元组的j与N中三元组的i相同才相乘 因而要记录N中每一行的第一个非零元和最后一个非零元在三元组中的位置,行逻辑顺序表类型 typedef struct Triple dataMAXSIZE+1; /非零元素三元组表int rposMAXRC+1; /各行第一个非零元素的位置表int mu, nu, tu; /矩阵的行数、列数和非零元素个数 RLSMatrix;,M.data=(1,1,3), (1,4,5), (2,2,-1), (3,1,2) ),M.rpos:,M.mu=3 M.nu=4 M.tu=4,可能与(1,1,3)相乘的元素有:(1,1

18、,1)、(1,2,2),可能与(1,4,5)相乘的元素有:(4,1,-2),可能与(3,1,2)相乘的元素有:(1,1,1)、(1,2,2),M.data=(1,1,3), (1,4,5), (2,2,-1), (3,1,2) ),M.rpos:,M.mu=3 M.nu=4 M.tu=4,row 1 2 3 rposrow 1 3 4,N.data=(1,1,1), (1,2,2), (3,2,4), (4,1,-2) ) N.rpos:,1 20 00 4 -2 0,N.mu=4 N.nu=2 N.tu=4,第1行:,(1,4,5) (4,1,-2),3 0 0 5 0 -1 0 0 2 0

19、 0 0,M.data=(1,1,3), (1,4,5), (2,2,-1), (3,1,2) ),M.rpos:,M.mu=3 M.nu=4 M.tu=4,row 1 2 3 ropsrow 1 3 4,N.data=(1,1,1), (1,2,2), (3,2,4), (4,1,-2) ) N.rpos:,1 20 00 4 -2 0,row 1 2 3 4 rposrow 1 3 3 4,N.mu=4 N.nu=2 N.tu=4,(1,1,3)(1,1,1),(1,1,3)(1,2,2),Q初始化; if(Q是非零矩阵) /逐行求积for(arow=1;arow=M.mu;+arow)

20、/处理M的每一行 ctemp=0; /累加器清零计算Q中第arow行的积并存入ctemp中;将ctemp中非零元素压缩存储到Q.data;/for arow /if,两个稀疏矩阵相乘(Q=M*N)的大致过程:,Status MultSMatrix(RLSMatrix M, RLSMatrix N,RLSMatrix ,for(p=M.rposarow; pM.rposarow+1; +p) /对当前行中每一个非零元素brow=M.datap.j; /找到对应元素在N中的行号if(browN.nu) t=N.ropsbrow+1;else t=N.tu+1;for(q=N.rposbrow;qt

21、;+q) ccol=N.dataq.j /乘积元素在Q中的列号ctempccol+=M.datap.e*N.dataq.e/for q/求得Q中第crow(=arow)行的非零元素,for(ccol=1;ccolMAXSIZE) return ERROR; Q.dataQ.tu=arow,ccol,ctempccol;/if/for arow/ifreturn OK; /MultSMatrix,(3)十字链表,当稀疏矩阵中非零元的个数和位置变化较大时, 可采用链式存储结构:,同一行的非零元通过right链接成一个线性表 同一列的非零元通过down链接成一个线性表,3 0 0 5 0 -1 0

22、02 0 0 0,/- - - - -稀疏矩阵的十字链表表示和建立十字链表的算法- - - - - typedef struct OLNode int i,j; /该非零元素的行和列下标ElemType e;struct OLNode *right,*down; /该非零元素所在行表和列表的后继链域 OLNode; *OLink; typedef struct OLink *rhead,*chead; /行和列链表头指针向量基址由CreatSMATRIX分配int mu, nu, tu; /稀疏矩阵的行数、列数和非零元素个数 CrossList;,Status CreatSMatrix_OL(

23、CrossList /初始化行列头指针向量;各行列链表为空链表,for(scanf( /完成行插入,if(M.cheadj=NULL) M.cheadj=p; else /寻查在列表插入的位置for(q=M.cheadj;(q-down) /CreatSMatrix_OL,3 -2 0 4 0 3 2 -7 0 0 1 0 0 0 0 0,1 2 0 0 -1 0 0 10 0 1 00 1 0 0,1.初始化: /pa、pb分别指向A、B的第一行第一个非零元素 pa=A.rhead1; pb=B.rhead1; pre=NULL; /pre为pa的前驱 i=1; for(j=1; j=A.n

24、u; +j) h1j=A.cheadj;,十字链表表示的稀疏矩阵的加法:A=A+B,2.每一行做 do while(pb!=NULL),if (pa= =NULL | pa-j pb-j)复制一个与pb内容相同的结点p;if (pre=NULL) A.rhaedp-i=p;else pre-right=p;p-right=pa; pre=p;/把p插入到相应的列链表中if (A.cheadp-j =NULL)A.cheadp-j=p; p-down=NULL; else if (h1p-j=A.cheadp-j) p-down=h1p-j;A.cheadp-j=p; elsep-down=h1

25、p-j-down;h1p-j-down=p; h1p-j=p; pb=pb-right;,2.每一行做 do while(pb!=NULL),if (pa!=NULL ,2.每一行做 do while(pb!=NULL),3. i+;pa=A.rheadi; pb=B.rheadi;pre=NULL; 重复2,直到i = =n+1为止,if (pa!=NULL ,54广义表,一、广义表的表示广义表一般记作:LS=(a1,a2,an)其中:LS为广义表的名称,n为广义表的长度,ai为广义表的元素每个元素既可以是单个不可分的元素-广义表LS的原子也可以是一个广义表-广义表LS的子表 一般用大写字母

26、表示广义表的名称,用小写字母表示原子非空广义表的第一个元素称为LS的表头(head)其余元素组成的表称为LS的表尾(tail),广义表是线性表的推广,又称列表,1广义表是一个多层次的结构 2广义表可以为其他广义表所共享 3广义表可以是一个递归的表 4()与()不同,二、广义表特性,例: A=( )B=(e)C=(a ,(b ,c ,d)D=(A , B , C)E=(a , E),三、抽象数据类型广义表定义 ADT Glist 数据对象:D=ei|i=1,2,n; n0;eiAtomSet或eiGlist,AtomSet为某个数据对象数据关系:R1=|ei-1,eiD, 2in基本操作:Ini

27、tGlist(初始条件:广义表L存在。操作结果:销毁广义表L,CopyGlist(初始条件:广义表L存在。操作结果:取广义表L的头。,GetTail(L);初始条件:广义表L存在。操作结果:取广义表L的尾。 InsertFirst_GL(初始条件:广义表L存在。操作结果:遍历广义表L,用函数Visit处理每个元素。 ADT Glist,5.5广义表的存储结构,/- - - - -广义表的头尾链表存储表示- - - - - typedef enum ATOM, LIST ElemTag; /ATOM= =0:原子 LIST= =1:子表 typedef struct GLNode ElemTag

28、 tag; /公共部分,用于区分原子结点和表结点union /原子结点和表结点的联合部分AtomType atom;/atom是原子结点的值域, AtomType由用户定义struct struct GLNode *hp, *tp;ptr;/ ptr是表结点的指针域,ptr.hp和ptr.tp分别指向表头和表尾; *GList; /广义表类型,A=( ) B=(e) C=(a ,(b ,c ,d) D=(A , B , C) E=(a , E),原子和子表所在层次清晰,最高层的表结点个数为广义表长度,非空广义表的头指针均指向一个表结点,广义表的另一种存储结构-扩展线性存储 typedef en

29、um ATOM, LIST ElemTag; /ATOM= =0:原子 LIST= =1:子表 typedef struct GLNode ElemTag tag; /公共部分,用于区分原子结点和表结点union /原子结点和表结点的联合部分AtomType atom /原子结点的值域struct GLNode *hp; /表结点的表头指针 ;struct GLNode *tp; /相当于线性链表的next,指向下一个元素结点 *GList; /广义表类型GList是一种扩展线性链表,A=( ) B=(e) C=(a ,(b ,c ,d) D=(A , B , C) E=(a , E),第二层结点个数为表的长度,能体现原子之间的层次关系,任一表都有一个表结点,

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

当前位置:首页 > 中等教育 > 小学课件

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


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

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

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