数据结构教案(苏2).ppt
- 文档编号:18630752
- 上传时间:2023-08-23
- 格式:PPT
- 页数:581
- 大小:2.92MB
数据结构教案(苏2).ppt
《数据结构教案(苏2).ppt》由会员分享,可在线阅读,更多相关《数据结构教案(苏2).ppt(581页珍藏版)》请在冰点文库上搜索。
第5章数组和广义表,数组是一种人们非常熟悉的数据结构,几乎所有的程序设计语言都支持这种数据结构或将这种数据结构设定为语言的固有类型。
数组这种数据结构可以看成是线性表的推广。
科学计算中涉及到大量的矩阵问题,在程序设计语言中一般都采用数组来存储,被描述成一个二维数组。
但当矩阵规模很大且具有特殊结构(对角矩阵、三角矩阵、对称矩阵、稀疏矩阵等),为减少程序的时间和空间需求,采用自定义的描述方式。
广义表是另一种推广形式的线性表,是一种灵活的数据结构,在许多方面有广泛的应用。
5.1数组的定义,数组是一组偶对(下标值,数据元素值)的集合。
在数组中,对于一组有意义的下标,都存在一个与其对应的值。
一维数组对应着一个下标值,二维数组对应着两个下标值,如此类推。
数组是由n(n1)个具有相同数据类型的数据元素a1,a2,an组成的有序序列,且该序列必须存储在一块地址连续的存储单元中。
数组中的数据元素具有相同数据类型。
数组是一种随机存取结构,给定一组下标,就可以访问与其对应的数据元素。
数组中的数据元素个数是固定的。
5.1.1数组的抽象数据类型定义,1.抽象数据类型定义ADTArray数据对象:
ji=0,1,bi-1,1,2,n;D=aj1j2jn|n0称为数组的维数,bi是数组第i维的长度,ji是数组元素第i维的下标,aj1j2jnElemSet数据关系:
R=R1,R2,RnRi=|0jkbk-1,1kn且ki,0jibi-2,aj1j2ji+1jnD基本操作:
ADTArray,由上述定义知,n维数组中有b1b2bn个数据元素,每个数据元素都受到n维关系的约束。
2.直观的n维数组以二维数组为例讨论。
将二维数组看成是一个定长的线性表,其每个元素又是一个定长的线性表。
设二维数组A=(aij)mn,则A=(1,2,p)(p=m或n)其中每个数据元素j是一个列向量(线性表):
j=(a1j,a2j,amj)1jn或是一个行向量:
i=(ai1,ai2,ain)1im如图5-1所示。
5.2数组的顺序表示和实现,数组一般不做插入和删除操作,也就是说,数组一旦建立,结构中的元素个数和元素间的关系就不再发生变化。
因此,一般都是采用顺序存储的方法来表示数组。
问题:
计算机的内存结构是一维(线性)地址结构,对于多维数组,将其存放(映射)到内存一维结构时,有个次序约定问题。
即必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放到内存中。
二维数组是最简单的多维数组,以此为例说明多维数组存放(映射)到内存一维结构时的次序约定问题。
通常有两种顺序存储方式行优先顺序(RowMajorOrder):
将数组元素按行排列,第i+1个行向量紧接在第i个行向量后面。
对二维数组,按行优先顺序存储的线性序列为:
a11,a12,a1n,a21,a22,a2n,am1,am2,amnPASCAL、C是按行优先顺序存储的,如图5-2(b)示。
列优先顺序(ColumnMajorOrder):
将数组元素按列向量排列,第j+1个列向量紧接在第j个列向量之后,对二维数组,按列优先顺序存储的线性序列为:
a11,a21,am1,a12,a22,am2,an1,an2,anmFORTRAN是按列优先顺序存储的,如图5-2(c)。
设有二维数组A=(aij)mn,若每个元素占用的存储单元数为d(个),LOCa11表示元素a11的首地址,即数组的首地址。
1.以“行优先顺序”存储第1行中的每个元素对应的(首)地址是:
LOCa1j=LOCa11+(j-1)dj=1,2,n
(2)第2行中的每个元素对应的(首)地址是:
LOCa2j=LOCa11+nd+(j-1)dj=1,2,n第m行中的每个元素对应的(首)地址是:
LOCamj=LOCa11+(m-1)nd+(j-1)dj=1,2,n,由此可知,二维数组中任一元素aij的(首)地址是:
LOCaij=LOCa11+(i-1)n+(j-1)d(5-1)i=1,2,mj=1,2,n根据(5-1)式,对于三维数组A=(aijk)mnp,若每个元素占用的存储单元数为d(个),LOCa111表示元素a111的首地址,即数组的首地址。
以“行优先顺序”存储在内存中。
三维数组中任一元素aijk的(首)地址是:
LOC(aijk)=LOCa111+(i-1)np+(j-1)p+(k-1)d(5-2),例如,二维数组Amn按“行优先顺序”存储在内存中,假设每个元素占用d个存储单元。
元素aij的存储地址应是数组的基地址加上排在aij前面的元素所占用的单元数。
因为aij位于第i行、第j列,前面i-1行一共有(i-1)n个元素,第i行上aij前面又有j-1个元素,故它前面一共有(i-1)n+j-1个元素,因此,aij的地址计算函数为:
LOC(aij)=LOC(a11)+(i-1)*n+j-1*d同样,三维数组Amnp按“行优先顺序”存储,其地址计算函数为:
LOC(aijk)=LOC(a111)+(i-1)*n*p+(j-1)*p+(k-1)*d,上述讨论均是假设数组各维的下界是不是1,更一般的二维数组是Ac1.d1,c2.d2,这里c1,c2不一定是1。
aij前一共有i-c1行,二维数组一共有d2-c2+1列,故这i-c1行共有(i-c1)*(d2-c2+1)个元素,第i行上aij前一共有j-c2个元素,因此,aij的地址计算函数为:
LOC(aij)=LOC(ac1c2)+(i-c1)*(d2-c2+1)+j-c2)*d例如,在C语言中,数组各维下标的下界是0,因此在C语言中,二维数组的地址计算公式为:
LOC(aij)=LOC(a00)+(i*(d2+1)+j)*d,2.以“列优先顺序”存储第1列中的每个元素对应的(首)地址是:
LOCaj1=LOCa11+(j-1)lj=1,2,m
(2)第2列中的每个元素对应的(首)地址是:
LOCaj2=LOCa11+ml+(j-1)lj=1,2,m第n列中的每个元素对应的(首)地址是:
LOCajn=LOCa11+(n-1)ml+(j-1)lj=1,2,m由此可知,二维数组中任一元素aij的(首)地址是:
LOCaij=LOCa11+(i-1)m+(j-1)l(5-1)i=1,2,nj=1,2,m,5.3矩阵的压缩存储,在科学与工程计算问题中,矩阵是一种常用的数学对象,在高级语言编程时,通常将一个矩阵描述为一个二维数组。
这样,可以对其元素进行随机存取,各种矩阵运算也非常简单。
对于高阶矩阵,若其中非零元素呈某种规律分布或者矩阵中有大量的零元素,若仍然用常规方法存储,可能存储重复的非零元素或零元素,将造成存储空间的大量浪费。
对这类矩阵进行压缩存储:
多个相同的非零元素只分配一个存储空间;零元素不分配空间。
5.3.1特殊矩阵,特殊矩阵:
是指非零元素或零元素的分布有一定规律的矩阵。
1.对称矩阵若一个n阶方阵A=(aij)nn中的元素满足性质:
aij=aji1i,jn且ij则称A为对称矩阵,如图5-3所示。
对称矩阵中的元素关于主对角线对称,因此,让每一对对称元素aij和aji(ij)分配一个存储空间,则n2个元素压缩存储到n(n+1)/2个存储空间,能节约近一半的存储空间。
不失一般性,假设按“行优先顺序”存储下三角形(包括对角线)中的元素。
设用一维数组(向量)sa0n(n+1)/2存储n阶对称矩阵,如图5-4所示。
为了便于访问,必须找出矩阵A中的元素的下标值(i,j)和向量sak的下标值k之间的对应关系。
若ij:
aij在下三角形中,直接保存在sa中。
aij之前的i-1行共有元素个数:
1+2+(i-1)=i(i-1)/2而在第i行上,aij之前恰有j-1个元素,因此,元素aij保存在向量sa中时的下标值k之间的对应关系是:
k=i(i-1)/2+j-1ij若ij:
则aij是在上三角矩阵中。
因为aij=aji,在向量sa中保存的是aji。
依上述分析可得:
k=j(j-1)/2+i-1ij对称矩阵元素aij保存在向量sa中时的下标值k与(i,j)之间的对应关系是:
根据上述的下标对应关系,对于矩阵中的任意元素aij,均可在一维数组sa中唯一确定其位置k;反之,对所有k=0,1,2,n(n+1)/2-1,都能确定sak中的元素在矩阵中的位置(i,j)。
称sa0n(n+1)/2为n阶对称矩阵A的压缩存储。
2.三角矩阵以主对角线划分,三角矩阵有上三角和下三角两种。
上三角矩阵的下三角(不包括主对角线)中的元素均为常数c(一般为0)。
下三角矩阵正好相反,它的主对角线上方均为常数,如图5-5所示。
三角矩阵中的重复元素c可共享一个存储空间,其余的元素正好有n(n+1)/2个,因此,三角矩阵可压缩存储到向量sa0n(n+1)/2中,其中c存放在向量的最后1个分量中。
下三角矩阵元素aij保存在向量sa中时的下标值k与(i,j)之间的对应关系是:
上三角矩阵的第p行有n-p+1个元素,元素aij前有i-1行,p从第一行1到i-1行累加每行元素个数,保存在向量sa中时的下标值k与(i,j)之间的对应关系是:
3.对角矩阵矩阵中,除了主对角线和主对角线上或下方若干条对角线上的元素之外,其余元素皆为零。
即所有的非零元素集中在以主对角线为了中心的带状区域中,如图5-6所示。
如上图三对角矩阵,非零元素仅出现在主对角(aii,1in)上、主对角线上的那条对角线(aii+1,1in-1)、主对角线下的那条对角线上(ai+1i,1in-1)。
显然,当|i-j|1时,元素aij=0。
由此可知,一个k对角矩阵(k为奇数)A是满足下述条件:
当|i-j|(k-1)/2时,aij=0,对角矩阵可按行优先顺序或对角线顺序,将其压缩存储到一个向量中,并且也能找到每个非零元素和向量下标的对应关系。
仍然以三对角矩阵为例讨论。
当i=1,j=1、2,或i=n,j=n-1、n或1in-1,j=i-1、i、i+1的元素aij外,其余元素都是0。
对这种矩阵,当以按“行优先顺序”存储时,第1行和第n行是2个非零元素,其余每行的非零元素都要是3个,则需存储的元素个数为3n-2。
如图5-7所示三对角矩阵的压缩存储形式。
数组sa中的元素sak与三对角矩阵中的元素aij存在一一对应关系,在aij之前有i-1行,共有3(i-1)-1个非零元素,在第i行,有j-i+1个非零元素,这样,非零元素aij的地址为:
LOCaij=LOCa11+3(i-1)-1+(j-i+1)d=LOCa11+(2i+j-3)d上例中,a34对应着sa7,k=2i+j-3=23+4-3=7称sa03n-2是n阶三对角矩阵A的压缩存储。
上述各种特殊矩阵,其非零元素的分布都是有规律的,因此总能找到一种方法将它们压缩存储到一个向量中,并且一般都能找到矩阵中的元素与该向量的对应关系,通过这个关系,仍能对矩阵的元素进行随机存取。
5.3.2稀疏矩阵,稀疏矩阵(SparseMatrix):
对于稀疏矩阵,目前还没有一个确切的定义。
设矩阵A是一个nm的矩阵中有s个非零元素,设=s/(nm),称为稀疏因子,如果某一矩阵的稀疏因子满足0.05时称为稀疏矩阵,如图5-8所示。
稀疏矩阵的压缩存储,对于稀疏矩阵,采用压缩存储方法时,只存储非0元素。
必须存储非0元素的行下标值、列下标值、元素值。
因此,一个三元组(i,j,aij)唯一确定稀疏矩阵的一个非零元素。
如图5-8的稀疏矩阵A的三元组线性表为:
(1,2,12),(1,3,9),(3,1,-3),(3,8,4),(4,3,24),(5,2,18),(6,7,-7),(7,4,-6),1.三元组表,若以行序为主序,稀疏矩阵中所有非0元素的三元组,就可以得构成该稀疏矩阵的一个三元组顺序表。
相应的数据结构定义如下:
三元组结点定义#defineMAX_SIZE101typedefintelemtype;typedefstructinti;/*行下标*/intj;/*列下标*/elemtypev;/*元素值*/Triple;,三元组顺序表定义typedefstructintrn;/*行数*/intcn;/*列数*/inttn;/*非0元素个数*/TripledataMAX_SIZE;TMatrix;图5-8所示的稀疏矩阵及其相应的转置矩阵所对应的三元组顺序表如图5-9所示。
矩阵的运算包括矩阵的转置、矩阵求逆、矩阵的加减、矩阵的乘除等。
在此,先讨论在这种压缩存储结构下的求矩阵的转置的运算。
一个mn的矩阵A,它的转置B是一个nm的矩阵,且bij=aji,0in,0jm,即B的行是A的列,B的列是A的行。
设稀疏矩阵A是按行优先顺序压缩存储在三元组表a.data中,若仅仅是简单地交换a.data中i和j的内容,得到三元组表b.data,b.data将是一个按列优先顺序存储的稀疏矩阵B,要得到按行优先顺序存储的b.data,就必须重新排列三元组表b.data中元素的顺序。
求转置矩阵的基本算法思想是:
将矩阵的行、列下标值交换。
即将三元组表中的行、列位置值i、j相互交换;重排三元组表中元素的顺序。
即交换后仍然是按行优先顺序排序的。
方法一:
算法思想:
按稀疏矩阵A的三元组表a.data中的列次序依次找到相应的三元组存入b.data中。
每找转置后矩阵的一个三元组,需从头至尾扫描整个三元组表a.data。
找到之后自然就成为按行优先的转置矩阵的压缩存储表示。
voidTransMatrix(TMatrixa,TMatrix,算法分析:
本算法主要的工作是在p和col的两个循环中完成的,故算法的时间复杂度为O(cntn),即矩阵的列数和非0元素的个数的乘积成正比。
而一般传统矩阵的转置算法为:
for(col=1;col=n;+col)for(row=0;row=m;+row)bcolrow=arowcol;其时间复杂度为O(nm)。
当非零元素的个数tn和mn同数量级时,算法TransMatrix的时间复杂度为O(mn2)。
由此可见,虽然节省了存储空间,但时间复杂度却大大增加。
所以上述算法只适合于稀疏矩阵中非0元素的个数tn远远小于mn的情况。
方法二(快速转置的算法)算法思想:
直接按照稀疏矩阵A的三元组表a.data的次序依次顺序转换,并将转换后的三元组放置于三元组表b.data的恰当位置。
前提:
若能预先确定原矩阵A中每一列的(即B中每一行)第一个非0元素在b.data中应有的位置,则在作转置时就可直接放在b.data中恰当的位置。
因此,应先求得A中每一列的非0元素个数。
附设两个辅助向量num和cpot。
numcol:
统计A中第col列中非0元素的个数;cpotcol:
指示A中第一个非0元素在b.data中的恰当位置。
显然有位置对应关系:
例图5-8中的矩阵A和表5-9(a)的相应的三元组表可以求得numcol和cpotcol的值如表5-1:
快速转置算法如下:
voidFastTransMatrix(TMatrixa,TMatrixb)intp,q,col,k;intnumMAX_SIZE,coptMAX_SIZE;b.rn=;=a.rn;b.tn=a.tn;/*置三元组表b.data的行、列数和非0元素个数*/if(b.tn=0)printf(“TheMatrixA=0n”);elsefor(col=1;col=;+col)numcol=0;/*向量num初始化为0*/for(k=1;k=a.tn;+k)+numa.datak.col;/*求原矩阵中每一列非0元素个数*/,for(cpot0=1,col=2;col=;+col)cpotcol=cpotcol-1+numcol-1;/*求第col列中第一个非0元在b.data中的序号*/for(p=1;p=a.tn;+p)col=a.datap.col;q=cpotcol;b.dataq.row=a.datap.col;b.dataq.col=a.datap.row;b.dataq.value=a.datap.value;+cpotcol;/*至关重要!
当本列中*/,2.行逻辑链接的三元组表,将上述方法二中的辅助向量cpot固定在稀疏矩阵的三元组表中,用来指示“行”的信息。
得到另一种顺序存储结构:
行逻辑链接的三元组顺序表。
其类型描述如下:
#defineMAX_ROW100typedefstructTripledataMAX_SIZE;/*非0元素的三元组表*/intrposMAX_ROW;/*各行第一个非0位置表*/intrn,cn,tn;/*矩阵的行、列数和非0元个数*/RLSMatrix;,稀疏矩阵的乘法设有两个矩阵:
A=(aij)mn,B=(bij)np则:
C=(cij)mp其中cij=aikbkj1kn,1im,1jp经典算法是三重循环:
for(i=1;i=m;+i)for(j=1;j=p;+j)cij=0;for(k=1;k=n;+k)cij=cij+aikbkj;此算法的复杂度为O(mnp)。
设有两个稀疏矩阵A=(aij)mn,B=(bij)np,其存储结构采用行逻辑链接的三元组顺序表。
算法思想:
对于A中的每个元素a.datap(p=1,2,a.tn),找到B中所有满足条件:
a.datap.col=b.dataq.row的元素b.dataq,求得a.datap.valueb.dataq.value,该乘积是cij中的一部分。
求得所有这样的乘积并累加求和就能得到cij。
为得到非0的乘积,只要对a.data1a.tn中每个元素(i,k,aik)(1ia.rn,),找到b.data中所有相应的元素(k,j,bkj)(1kb.rn,)相乘即可。
则必须知道矩阵B中第k行的所有非0元素,而b.rpos向量中提供了相应的信息。
b.rposrow指示了矩阵B的第row行中第一个非0元素在b.data中的位置(序号),显然,b.rposrow+1-1指示了第row行中最后一个非0元素在b.data中的位置(序号)。
最后一行中最后一个非0元素在b.data中的位置显然就是b.tn。
两个稀疏矩阵相乘的算法如下:
voidMultsMatrix(RLSMatrixa,RLSMatrixb,RLSMatrixc)/*求矩阵A、B的积C=AB,采用行逻辑链接的顺序表*/elemtypectempMax_Size;intp,q,arow,ccol,brow,t;if(!
=b.rn)printf(“Errorn”);exit(0);,elsec.rn=a.rn;=b.n;c.tn=0;/*初始化C*/if(a.tn*b.tn!
=0)/*C是非零矩阵*/for(arow=1;arow=a.rn;+arow)ctemparow=0;/*当前行累加器清零*/c.rposarow=c.tn+1;p=a.ropsarow;for(;pa.rposarow+1;+p)/*对第arow行的每一个非0元素*/brow=a.datap.col;/*找到元素在b.data中的行号*/if()t=(b.rposbrow+1;elset=b.tn+1;,for(q=b.rposbrow;qMAX_SIZE)printf(“Errorn”);exit(0);else,c.datac.tn=(arow,ccol,ctempccol);,3.十字链表,对于稀疏矩阵,当非0元素的个数和位置在操作过程中变化较大时,采用链式存储结构表示比三元组的线性表更方便。
矩阵中非0元素的结点所含的域有:
行、列、值、行指针(指向同一行的下一个非0元)、列指针(指向同一列的下一个非0元)。
其次,十字交叉链表还有一个头结点,结点的结构如图5-10所示。
由定义知,稀疏矩阵中同一行的非0元素的由right指针域链接成一个行链表,由down指针域链接成一个列链表。
则每个非0元素既是某个行链表中的一个结点,同时又是某个列链表中的一个结点,所有的非0元素构成一个十字交叉的链表。
称为十字链表。
此外,还可用两个一维数组分别存储行链表的头指针和列链表的头指针。
对于图5-11(a)的稀疏矩阵A,对应的十字交叉链表如图5-11(b)所示,结点的描述如下:
typedefstructClnodeintrow,col;/*行号和列号*/elemtypev;/*元素值*/structClnode*down,*right;OLNode;/*非0元素结点*/,typedefstructClnodeintrn;/*矩阵的行数*/intcn;/*矩阵的列数*/inttn;/*非0元素总数*/OLNode*rheadcn+1;OLNode*cheadrn+1;CrossList;,5.4广义表,广义表是线性表的推广和扩充,在人工智能领域中应用十分广泛。
在第2章中,我们把线性表定义为n(n0)个元素a1,a2,an的有穷序列,该序列中的所有元素具有相同的数据类型且只能是原子项(Atom)。
所谓原子项可以是一个数或一个结构,是指结构上不可再分的。
若放松对元素的这种限制,容许它们具有其自身结构,就产生了广义表的概念。
广义表(Lists,又称为列表):
是由n(n0)个元素组成的有穷序列:
LS=(a1,a2,an),其中ai或者是原子项,或者是一个广义表。
LS是广义表的名字,n为它的长度。
若ai是广义表,则称为LS的子表。
习惯上:
原子用小写字母,子表用大写字母。
若广义表LS非空时:
a1(表中第一个元素)称为表头;其余元素组成的子表称为表尾;(a2,a3,an)广义表中所包含的元素(包括原子和子表)的个数称为表的长度。
广义表中括号的最大层数称为表深(度)。
有关广义表的这些概念的例子如表5-2所示。
表5-2广义表及其示例,广义表的重要结论:
广义表的元素可以是原子,也可以是子表,子表的元素又可以是子表,。
即广义表是一个多层次的结构。
表5-2中的广义表D的图形表示如图5-12所示。
(2)广义表可以被其它广义表所共享,也可以共享其它广义表。
广义表共享其它广义表时通过表名引用。
(3)广义表本身可以是一个递归表。
(4)根据对表头、表尾的定义,任何一个非空广义表的表头可以是原子,也可以是子表,而表尾必定是广义表。
5.4.1广义表的存储结构,由于广义表中的数据元素具有不同的结构,通常用链式存储结构表示,每个数据元素用一个结点表示。
因此,广义表中就有两类结点:
一类是表结点,用来表示广义表项,由标志域,表头指针域,表尾指针域组成;另一类是原子结点,用来表示原子项,由标志域,原子的值域组成。
如图5-13所示。
只要广义表非空,都是由表头和表尾组成。
即一个确定的表头和表尾就唯一确定一个广义表。
相应的数据结构定义如下:
typedefstructGLNodeinttag;/*标志域,为1:
表结点;为0:
原子结点*/unionelemtypevalue;/*原子结点的值域*/structstructGLNode*hp,*tp;ptr;/*ptr和atom两成员共用*/Gdata;GLNode;/*广义表结点类型*/,例:
对A=(),B=(e),C=(a,(b,c,d),D=(A,B,C),E=(a,E)的广义表的存储结构如图5-14所示。
对于上述存储结构,有如下几个特点:
(1)若广义表为空,表头指针为空;否则,表头指针总是指向一个表结点,其中hp指向广义表的表头结点(或为原子结点,或为表结点),tp指向广义表的表尾(表尾为空时,指针为空,否则必为表结点)。
(2)这种结构求广义表的长度、深度、表头、表尾的操作十分方便。
(3)表结点太多,造成空间浪费。
也可用图5-15所示的结点结构。
习题五,什么是广义表?
请简述广义表与线性表的区别?
一个广义表是(a,(a,b),d,e,(a,(i,j),k),请画出该广义表的链式存储结构。
设有二维数组a68,每个元素占相邻的4个字节,存储器按字节编址,已知a的起始地址是1000,试计算:
数组a的最后一个元素a57起始地址;按行序优先时,元素a4
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 教案