数据结构-用C语言描述(第二版)第5章数组和广义表.ppt
《数据结构-用C语言描述(第二版)第5章数组和广义表.ppt》由会员分享,可在线阅读,更多相关《数据结构-用C语言描述(第二版)第5章数组和广义表.ppt(51页珍藏版)》请在三一办公上搜索。
1、5.1 数组及其运算5.2 数组的顺序存储结构 5.3 矩阵的压缩存储5.4 广义表5.5 m元多项式的表示,第5章 数组和广义表,第5章 数组和广义表,本章前几章所讨论的线性表、栈、队列和串都是线性的数据结构。它们的组成元素的值都是不可分解的。本章将要讨论的多维数组和广义表是一种复杂的非线性结构,它的组成元素是可以分解的,每个元素可以有多个的直接前趋和直接后继。本章主要介绍数组的概念及多维数组在计算机中的存放,特殊矩阵的压缩存储及相应运算,广义表的概念和存储结构及其相关运算的实现。,5.1 数组及其计算,几乎所有的程序设计语言中都有利用数组来描述数据。由于数组中的各元素具有统一的类型,而且数
2、组元素的下标具有固定的上下界,所以,它比其它复杂的数据结构更容易处理。根据数组元素的组织形式不同,数组可以分为一维数组、二维数组以及多维(n维)数组。例如,二维数组,它由固定数量的mn个元素所组成,且每个数据元素aij均受两个下标关系约束。除边界外,每个数据元素都有两个直接前趋和直接后继结点,即行关系上的直接前趋aij-1和直接后继aij+1,列关系上的直接前趋ai-1j 和直接后继ai+1j,而且仅有一个开始结点a00,它没有直接前趋;仅有一个终端结点an-1n-1,它没有直接后继;而边界上的结点除开始和终端结点外,每个结点均只有一个直接前趋或只有一个直接后继,因此,二维数组可以看作是线性表
3、的推广。同时,二维数组可看作是由二个一维数组作为数据元素定义的一维数组,数据元素之间在每一个关系中仍具有线性特性,但在整个结构中呈非线性关系。如图5.1所示。同样,三维数组A mnp可以看作是其数据元素为二维数组表示的特殊线性表,每个元素最多可以有三个直接前趋和三个直接后继,;依此类推,n维数组中的每个元素最多可以有n个直接前趋和n个直接后继。由此可知,多维数组是一种复杂的数据结构,且也可以看作是线性结构的推广。对于一个数组结构而言,一般只有存取元素和修改元素值两种运算。,A mn=((a00,a01,a 0n-1),(a10,a11,a1n-1),(am-10,a m11,,a m-1n-1
4、))图5.1 二维数组图例,数组的顺序存储结构指的是如何在计算机内存中利用一组地址连续的存储单元来存储数组元素的存储方式。由于计算机存储单元都是一维的结构,而多维数组是一个多维的结构,因此,要存放多维数组结构必须有一个次序约定的问题。例如,一个二维数组,可以有两种存储方式:一是以行为主序的优先存储方式,即数组元素按行优先关系排列,第i+1行的数据元素紧跟在第i行的数据元素之后,而同一行中的数据元素以列下标递增次序排列。二是以列为主序的优先存储方式,即数组元素按列优先关系排列,第j+1列中的数据元素紧跟在第j列中的数据元素后面,同一列中的元素以行下标递增次序排列,如图5.2所示。,5.2 数组的
5、顺序存储结构,图5.2 二维数组的两种存储方式,由于多维数组其下标不只2个,一般规定以下标顺序或以逆下标顺序为主序的优先存储方式。顺序存储的数组是一个随机存取结构。多维数组的数据元素存储地址的计算。一个二维数组Amn,若以行为主序优先存储,且已知a00的存储地址LOC(a00)(即二维数组A的起始存储位置,亦称为基地址或基址)和每个数据元素所占用的存储单元个数c,则二维数组中任一数据元素ai,j的存储地址可由下式确定:LOC(aij)=LOC(a00)+(in+j)c同理可推导出以列为主序优先存储时数据元素aij的存储地址,其计算公式为:LOC(a i j)=LOC(a00)+(j n+i)c
6、 对于三维数组 A mnp而言,若以行为主序优先存储时,则其数据元素aijk的存储地址可为:LOC(a i j k)=LOC(a000)+i m p+j p+k c 对于一般的二维数组Ac1d1,c2d2而言,此处c1,c2的值不一定是0,a i j 的地址为:LOC(a ij)=LOC(a c 1 c 2)+(i c 1)*(d 2 c 2+1)+j c 2*c,5.3 矩阵的压缩存储,在很多科学计算与工程应用中,经常要使用矩阵。它是由 m 行和 n 列的数值构成。在编程时,通常利用二维数组来存储矩阵。但在某些情况下,特别是在数值分析中经常会出现一些阶数很高的矩阵,其中含有许多值相同的元素或
7、零元素,若利用二维数组存储会浪费空间。为了节省存储空间并且加快处理速度,需要对这类矩阵进行压缩存储,也就是说可以对多个具有相同值的元素只分配一个存储空间,而对零元素则不分配空间。一般的,压缩存储适用于特殊矩阵和稀疏矩阵。特殊矩阵是指那些具有相同值的元素或零元素在矩阵中的分布有一定的规律矩阵;而稀疏矩阵是指那些零元素远远多于非零元素,并且非零元素的分布没有规律的矩阵。,5.3.1 特殊矩阵 1.三角矩阵 n阶三角矩阵以对角线划分有上三角与下三角矩阵两种。上三角矩阵是指矩阵的下三角(不含对角线)中的元素均为常数C或零的n阶矩阵,下三角矩阵则与之相反,如图5.3所示。,个元素,而在第i+1行上,ai
8、j是该行的第j-i+1个元素,从而可得存储单元Mk的下标与aij的下标i、j的对应关系为:,i/2(2n-i+1)+j-i 当ij k=n(n+1)/2 当i j,在压缩存储时,矩阵中值相同的元素C可共享一个存储空间,元素为零则可不必分配空间,而其余的元素有 n(n+1)/2个,因此三角矩阵可用一维数组Mn(n+1)/2+1来存储,其中常数C放在数组的最后一个下标变量中。上三角矩阵,主对角线之上的第p行(1pn)恰有n-p+1个元素,若按行为主序优先顺序存储,则aij之前的前i行共有:,同样,可得下三角矩阵的存储单元Mk 的下标与aij 的下标i、j的对应关系为:,i(i+1)/2+j 当ij
9、 k=n(n+1)/2 当i j,2.对称矩阵 若一个n阶方阵A中的元素满足下列性质:a ij=a ji 0i,jn-1则称A为对称矩阵,如一个4阶对称矩阵如图5.4所示。,图5.4 4阶对称矩阵示例,因此,可以按图5.5所示的次序将矩阵元素存放在一个一维数组Mn(n+1)/2中,其存储方式如图5.6所示。这样,给出对称矩阵A中的任一个元素aij,依据它的下标i和j就可由对应关系式确定其在数组M中的位置k,aij 的地址LOC(aij)可由下式计算:LOC(aij)=LOC(Mk)=LOC(M0)+kc=LOC(M0)+I(I+1)/2+J c 其中,c为每个数据元素所占的存储单元数目,且 I
10、=max(i,j),J=min(i,j)从而,k=I*(I+1)/2+J,即k为i,j统一后的值。,由于对称矩阵中的元素关于主对角线对称,所以可以只存储矩阵中主对角线(含对角线)以上或以下的元素,即只为每一对对称元素分配一个存储空间,将共有nn个的元素压缩存储到n(n+1)/2个存储空间中,从而节省了空间。假定按以行为主序优先方式存储主对角线(包括对角线)以下的元素,则其存储次序如图5.5所示。在上述的下三角矩阵中,矩阵元素总数为:,图5.5 对称矩阵的行优先排列存放,K=0 1 2 n(n+1)/2-1,图5.6 对称矩阵的压缩存储情况,5.3.2 稀疏矩阵 如果矩阵中非零元素的个数远远小于
11、矩阵元素的总数,并且非零元素的分布没有规律,则称此类矩阵为稀疏矩阵。稀疏矩阵的压缩存储,可以在存储非零元素的同时,存储适当的辅助信息。例如,可以利用一个三元组元素(i,j,aij)就可唯一地确定矩阵A中的非零元素,这样,稀疏矩阵可由表示非零元素的三元组及其行、列数唯一地确定。例如,稀疏矩阵A:,可由三元组表(0,1,5),(0,4,8),(1,0,1),(1,2,3),(2,1,-2),(3,0,6)加上(4,5)这一行、列数对来描述。,一般地,可以用三元组表表示法和十字链表作为稀疏矩阵的压缩存储方法,其中以三元组表示法最常用。1.三元组顺序表 若将表示稀疏矩阵的三元组按行优先(或列优先)的顺
12、序排列,则可得到一个结点均是三元组的线性表即三元组表,若以顺序存储结构来表示三元组表,则可得到稀疏矩阵的一种压缩存储方式,称为三元组顺序表。如图5.7所示为三元组以行为主序优先顺序存储的A稀疏矩阵所对应的三元组表。其类型定义为:#define MAXSIZE 999/*非零元素个数的最大值设为1000*/typedef struct int i,j;/*非零元素的行,列下标*/datatype v;/*元素值*/node;typedef struct int mu,nu,tu;/*行,列数,非零元素个数*/node dataMAXSIZE;/*三元组表*/matrix/*稀疏矩阵类型*/mat
13、rix*a;,图5.7 稀疏矩阵A所对应的三元组表a-data,(1)矩阵的转置 一个m n的稀疏矩阵A,它的转置矩阵B仍是稀疏矩阵,且为n m的矩阵,同时有Aij=Bji成立(0im-1,0jn-1),即B的行是A的列,B的列是A的行,如图5.8所示,A,B两矩阵互为转置。假设A和B矩阵分别用matrix型指针变量a和b表示,矩阵的转置可以按以下进行:由于的行是的列,所以可按照b-data三元组表的次序在a-data中找到相应的三元组进行转置,即可按a-data的列序转置,所得到的转置矩阵的三元组表b-data必定是按行优先存放的。因此,可以对三元组表a-data从第一行起扫描,找到的每一列
14、中所有的非零元素,就可以实现转置。算法描述如下:,matrix*transmatrix(matrix*a)int am,bn,col;matrix*b;/*转置后的矩阵b*/b=(matrix*)malloc(sizeof(matrix);b-mu=a-nu;b-nu=a-mu;/*行、列数目交换*/b-tu=a-tu;/*非零元素个数赋值*/if(b-tu0)bn=0;for(col=0;colnu;col+)/*按*a的列序转置*for(am=0;amtu;am+)/*扫描整个三元组表*if(a-data am.j=col)/*列号为col时转置*b-data bn.i=a-data am
15、.j;/*行、列交换*/b-data bn.j=a-data am.i;b-data bn.v=a-data am.v;bn+;/*b-data中的结点序号加1*return b;/*返回转置矩阵的指针*/*transmatrix*/以上算法的时间复杂度为(tunu)。一般的,上述转置算法只适用于当tumu nu的情况。,0im1-1,0jn2-1;,其算法可描述如下:,for(i=0;i m1;i+)for(j=0;j n2;j+)c i j=0;for(k=0;k n1;k+)c i j=ci j+ai k*bk j;,(2)矩阵的乘法 设矩阵m1n1与mn,当n1m时,可得矩阵相乘为:m
16、1xn2=Am1n1 Bm2n1 由矩阵乘法的定义得:,该算法的时间复杂度为(m1n1n2)。,要求C=A B,显然,在上述算法中,不论aik和bkj的值是否为零都要作一次乘法。由于在稀疏矩阵中存在大量的零元素,所以可以避免许多无用的运算。若利用三元组表作为稀疏矩阵的存储结构,只需在a-data和b-data中找到相应的各对元素(即a-data中j和b-data中的i相等的元素)相乘即可求得两矩阵的乘法值。例如,矩阵与B为:,它们对应的三元组表a-data,b-data和c-data分别如图5.9所示:,为了得到非零的乘积项,必须在b-data中查找矩阵B中第k行的所有非零元素。由于b-dat
17、a是以行为主序存放非零元素的三元组,若能预先确定矩阵B中每一行的第一个非零元素在b-data中应有的位置,就可以顺序存取b-data中第k行的所有非零元素。显然,应先求出B中的每一行中非零元素个数之后才可确定这些位置。为此,可用一个数组numm2-1存储每一行中非零元素的个数,用另一个数组rposm2-1存储每一个非零元素在b-data中所在的位置,从而应有以下式子成立。rpos 0=0 rpos row=rpos row-1+num row-1(1rowm2-1),例如,B矩阵其rpos数组的值可用下表表示:,由于rposrow表示B的第row行中第一个非零元素在b-data中的序号,所以r
18、posrow+1-1表示第row行中最后一个非零元素在b-data中的序号。显然,最后一行中最后一个非零元素在b-data中的位置就是rposm21(此时b.mu=m2),且有rposm2=rposm2-1+numm21。从而可以得到稀疏矩阵相乘的具体做法:对于A中的每个元素a-datap(p=0,1,2,m.tu-1),找到B中所有满足条件a-data p.j=b-data q.i的元素b-data q,然后求a-data p.v和b-data q.v的乘积,作为乘积矩阵累加和项ci j中的一部分。可以对每个元素设一个累计和的变量,初始时置各变量为零,然后扫描三元组表a-data,求得相应元
19、素的乘积并累加到累计和的变量上。乘积矩阵中的各元素只有在求得累加和后才可确定是否为零,由于c中元素的行号一致,且a中元素以A的行序为主序排序,所以可对c逐行处理。先求得累计求和的中间结果,然后再压缩存储到c-data中去。两矩阵相乘的算法如下:,matrix*mul(matrix*a,matrix*b)matrix*c;int crow,k,brow,p,t;int num,rpos;datatype ctemp;if(a-tu*b-tu!=0)for(crow=0;crow tu;crow+)numcrow=0;/*数组初始化*for(t=0;t tu;t+)numb-data t.i=nu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 语言 描述 第二 数组 广义
链接地址:https://www.31ppt.com/p-6296808.html