数据结构答案第6章多维数组和广义表学习指导

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

44第6章多维数组和广义表6.1知识点分析1.多维数组概念多维数组是向量的推广,对于二维数组Am×n既可以看成m行向量组成的向量,也可以看成n行向量组成的向量。多维数组在计算机中有两种存储形式:按行优先顺序存储和按列优先顺序存储。2.多维数组的存储二维数组aij的地址为:LOC(aij)=LOC(a00)+(i×n+j)×d(0下标起始的语言)三维数组aijk的地址为:LOC(aijk)=LOC(a000)+((i×n×p+j×p+k)×d(0下标起始的语言)d为每个数据元素占有的字节数。3.特殊矩阵在矩阵中非零元素或零元素的分布有一定规律的矩阵称为特殊矩阵,如三角矩阵、对称矩阵、稀疏矩阵等。当矩阵的阶数很大时,用普通的二维数组存储这些特殊矩阵将会占用很多的存储单元。从节约存储空间的角度考虑,以下特殊矩阵的存储方法。(1)对称矩阵对称矩阵是一种特殊矩阵,n阶方阵的元素满足性质:aij=aji(0≤i,j≤n-1)。对称矩阵是关于主对角线的对称,因此只需存储上三角或下三角部分的数据即可。(2)三角矩阵三角矩阵的特殊性是以主对角线划分矩阵。下三角矩阵,主对角线以上均为同一个常数;上三角矩阵,主对角线以下均为同一个常数,可以采用压缩存储。(3)稀疏矩阵在m*n的矩阵中有t个非零元素,且t远小于m×n,这样的矩阵称稀疏矩阵。为了节约存储空间,稀疏矩阵中零元素无需存储,只需存储矩阵中的非零元素。稀疏矩阵常用的有:三元组表存储、带行指针的链表存储、十字链表存储等存储方法。4.广义表广义表是n(n≥0)个数据元素的有序序列,广义表的元素可以是单元素,也可以是一个广义表。由于广义表的元素有两种形式,所以其结点的存储形式也有两种:(1)表结点由标志域、表头指针域、表尾指针域组成。(2)原子结点由标志域和值域组成。5.广义表与线性表的区别和联系线性表是具有相同类型的n个数据元素的有限序列,记为a1、a2、a3、……、an。广义表也是n个数据元素的有限序列,记为a1、a2、a3、……、an。线性表中的元素必须具有相同的类型,而广义表中的成员,既可以是单个元素(原子),也可以是一个广义表(子表)。当广义表中的每一个ai元素都是数据元素,且具有相同类型时,则它就是一个线性表,因此可以说广义表是线性表的一种推广,或者说线性表是广义表的一个特例。6.2典型习题分析【例1】设二维数组A5×6的每个元素占4个字节,存储器按字节编址。已知A的起始地址为2000,计算:(1)数组的大小?(2)A的终端结点a45的存储地址?(3)按行优先顺序存储时,a25的存储地址?(4)按列优先顺序存储时,a25的存储地址?答:45(1)数组的大小(即数组A共占多少字节):5×6×4=120B。(2)一个结点aij的存储地址是该结点所占用的存储空间的第1个字节的地址(即起始地址),它等于:基地址+排在aij之前的结点个数×每个结点所占用的字节数。a45的起始地址:LOC(a45)=2000+(4×6+5)×4=2116(3)在按行优先顺序存储时,排在aij之前的结点的个数为:在前i行(即0~i-1行)上共有i×n个结点,在第i行上aij之前有j个结点(0~j-1列)。所以按行优先存储的地址计算公式为:LOC(aij)=LOC(a00)+(i×n+j)×dLOC(a25)=2000+(2×6+5)×4=2068(4)在按列优先顺序存储时,排在aij之前的结点的个数为:在前j列(即0~j-1列)上共有j×m个结点,在第j列上aij之前有i个结点(0~i-1行)。所以按列优先存储的地址计算公式为:LOC(aij)=LOC(a00)+(j×m+i)×dLOC(a25)=2000+(5×5+2)×4=2108【例2】特殊矩阵和稀疏矩阵哪一种压缩存储后会失去随机存储功能?为什么?答:对于像三角矩阵等特殊矩阵由于压缩存储时将其存储在一个线性数组向量中,矩阵元素aij的下标i,j与它在向量中的对应元素bk下标k有一对应关系,故不会失去随机存储功能。而像稀疏矩阵,其压缩存储的方式是将其非零元素存储在一个三元组中,以三元组数组a[k]形式存储,矩阵元素aij下标i,j与数组中对应元素a[k]行下标k无对应关系,故失去随机存储功能。【例3】求矩阵的转置矩阵分析:对于一个m×n的矩阵Amn,其转置矩阵是一个n×m的矩阵Bnm,且B[i][j]=A[j][i],0≤in,0≤im。其函数如下:voidtrs(A,B)maxixA,B;{inti,j;for(i=0;im;i++)for(j=0;jn;j++)B[j][i]=A[i][j];}【例4】求两个矩阵的乘分析:设两个矩阵相乘:C=A×B,其中A是一个m×n的矩阵,B是一个n×k的矩阵,则C为一个m×k的矩阵。其函数如下:voidmut(C,A,B)maxixA,B,C;{inti,j,k;for(i=0;im;i++)for(j=0;jk;j++){C[i][j]=0;for(k=0;kn;k++)C[i][j]=C[i][j]+A[i][k]*B[k][j];}}【例5】若矩阵Am×n中存在一个元素aij,满足aij是第i行最小的元素,且是第j列最大的元素,则称aij是矩阵A的鞍点,请编写一个算法,找出矩阵A的所有鞍点。分析:找矩阵A的所有鞍点的基本思想是:先逐行找出本行值最小的元素,确定其所在的列,并在此列中选值最大的元素,若两者值相等,即选中一个鞍点。voidSpoint(int*a,intm,intn){inti,j,k,c,max,min,r=0;for(i=0;im;i++){min=a[i][0];//假设a[i][0]为最小c=0;46for(j=1;jn;j++)//本循环找出本行值最小的元素ifa[i][j]min{min=a[i][j];c=j;//c记录最小值的列值}max=a[0][c];for(k=1;km;k++)//本循环找出本列值最大的元素if(a[k][c]max)max=a[k][c];if(max==min)//max==min,即鞍点{printf(“\ni=%d,j=%d,a[i][j]=%d”,i,j,max);r++;//r记录鞍点的个数}}if(r==0)printf(“\nnosaddlepointer”);//无鞍点}【例6】试编写一个在以H为头的十字链表中查找数据为k的结点的算法。分析:每个非零元素作为一个结点,结点中除了表示非零元素所在的行(i)、列(j)、值(v)的三元组以外还有两个指针域,其结构如图6-1所示。其中:列指针域down用来指向本列中下一个非零元素;行指针域right用来指向本行中下一个非零元素。ijvdownright图6-1十字链表的结点结构结点的结构定义如下:typedefstructnode{introw,col;//定义行、列structnode*down,*right;//定义列指针、行指针union//定义一个共用体{intv;//定义值域structnode*next;//表头结点使用的next域}tag;};intSearchmat(structnode*H,intk,int*rown,int*coln){structnode*p,*q;p=H-tag.next;while(p!=H){q=p-right;while(p!=q){if(q-tag.v==k)//查找成功处理{*rown=q-row;*coln=q-colreturn1;}q=q-right;}47p=p-tag.next;}return0;}main()//主函数{structnode*H;inti,j,k;H=Createmat();//设创建十字链表的函数Createmat()已存在printf(“输入要查找的值:”);scanf(“%d“,&k);//输入要查找的值if(Searchmat(H,k,&i,&j))//调用查找函数printf(“%d在第%d行第%d列\n“,k,i,j);elseprintf(“查无此值!“);}【例7】已知广义表LS=((a,b,c),(d,e,f,g)),写出用取表头(Head)和取表尾(Tail)函数驱除取出原子e的运算。分析:L1=Tail(LS)=((d,e,f,g))L2=Head(L1)=(d,e,f,g)L3=Tail(L2)=(e,f,g)L4=Head(L3)=e所以取出原子的运算是Head(Tail(Head(Tail(L2))))=e【例8】画出广义表:A(a,B(b,d),C(e,B(b,d),L(A,f,g)))的图形表示。分析:在广义表中为了把单元素和表区分开来,一般用小写字母表示元素,用大写字母表示子表;在画图时用圆圈表示表,用方框表示元素,并用线段把表和它的元素连接起来,则可以得到如图6-2所示广义表的图形表示。【例9】设广义表采用如下存储结构:abdfegACLB图6-2广义表图形表结点为:tag=1hptp元素结点为:tag=0data48其C语言描述如下:typedefenum{ATOM,LIST}Elemtag;typedefstructGLNode{Elemtagtag;//公共部分,用于区分原素和表union//元素结点和表结点的联合部分{chardata;//元素结点的值域struct{structGLNode*hp,*tp;}ptr;//ptr是表结点的指针域,ptr.hp指向表头,ptr.tp指向表尾}}*Glist;在求广义表深度的递归算法中,若结点为原子则深度为0,若是空表深度为1,否则返回头指针与尾指针所指广义表的深度最大值,填空求表深度的递归算法。intGlistDepth(GlistL){intm,n;if(!L-tag)①elseif(②)return1;m=GlistDepth(③)+1;n=GlistDepth(④);returnmn?⑤;}答:①return0;②!L③L-ptr.hp④L-ptr.tp⑤m:n【例10】写一个算法,判断广义表中左、右括号是否配对。分析:可以将广义表视为一个字符串,依次扫描字符串中的字符,遇到“(”时入栈,遇到“)”时,出栈。扫描完毕,若栈空说明括号配对;否则括号不配对。其算法如下:intBracketMatch(char*s)//s为广义表{char*c;SeqStackT;c=S;InitStack(&T);//初始化栈While(*c!=’\0’);{if(*c==’(‘)Push(&T,*c);elseif(*c==’)’)if(StackEmpty(&T))return(0);//栈空,不能匹配,返回0elsePop(&T);49c++;}if(StackEmpty(&T))return(0);//栈不空,说明括号不配对,返回0elsereturn(1);//栈空,说明括号配对,返回1}6.3单元练习6解答一.判断题答案题目12345678910答案√√×√√×××√√二.填空题答案(1)按列优先顺序存储(2)随机(3)n(4)O(n*m)(5)LOC[1,2]=2000+(1*4+2)*4=2024(6)3(7)行数(8)n(n-1)/2(9)4(10)十字链表(11)广义表(或子表)(12)b(13)head(tail(tail(head(L))))(14)(c,d)(15)n(n-1)/2+1(16)n(17)3(18)4(19)∞(20)((b),((c,(d))))三.选择题答案题目12345678910答案DDDBABDBAB题目11121314151617181920答案DABBBDCCCD四.算法阅读题答案(1)分析:注意k的变化依次为:0,2,5,9,14,正好是aii在A中的存储位置。在循环中k每次增加i+2。第i行主对角线上的元素aii,其在A中的位置为:i(i+1)/2+i;(1)第i+1行主对角线上的元素ai+1i+1,其在A中的位置为:(i+1)(i+

1 / 8
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功