1、2.3 课后习题解答2.3.2 判断题1线性表的逻辑顺序与存储顺序总是一致的。()2顺序存储的线性表可以按序号随机存取。()3顺序表的插入和删除操作不需要付出很大的时间代价,因为每次操作平均只有近一半的元素需要移动。()4线性表中的元素可以是各种各样的,但同一线性表中的数据元素具有相同的特性,因此属于同一数据对象。()5在线性表的顺序存储结构中,逻辑上相邻的两个元素在物理位置上并不一定相邻。()6在线性表的链式存储结构中,逻辑上相邻的元素在物理位置上不一定相邻。()7线性表的链式存储结构优于顺序存储结构。()8在线性表的顺序存储结构中,插入和删除时移动元素的个数与该元素的位置有关。()9线性表
2、的链式存储结构是用一组任意的存储单元来存储线性表中数据元素的。()10在单链表中,要取得某个元素,只要知道该元素的指针即可,因此,单链表是随机存取的存储结构。()11静态链表既有顺序存储的优点,又有动态链表的优点。所以它存取表中第i个元素的时间与i无关。()12线性表的特点是每个元素都有一个前驱和一个后继。()2.3.3 算法设计题1设线性表存放在向量Aarrsize的前elenum个分量中,且递增有序。试写一算法,将x 插入到线性表的适当位置上,以保持线性表的有序性,并且分析算法的时间复杂度。【提示】直接用题目中所给定的数据结构(顺序存储的思想是用物理上的相邻表示逻辑上的相邻,不一定将向量和
3、表示线性表长度的变量封装成一个结构体),因为是顺序存储,分配的存储空间是固定大小的,所以首先确定是否还有存储空间,若有,则根据原线性表中元素的有序性,来确定插入元素的插入位置,后面的元素为它让出位置,(也可以从高下标端开始一边比较,一边移位)然后插入x ,最后修改表示表长的变量。int insert (datatype A,int *elenum,datatype x)/*设elenum为表的最大下标*/if (*elenum=arrsize-1) return 0;/*表已满,无法插入*/else i=*elenum; while (i=0 & Aix)/*边找位置边移动*/Ai+1=Ai;
4、i-; Ai+1=x;/*找到的位置是插入位的下一位*/ (*elenum)+;return 1;/*插入成功*/时间复杂度为O(n)。2已知一顺序表A,其元素值非递减有序排列,编写一个算法删除顺序表中多余的值相同的元素。【提示】对顺序表A,从第一个元素开始,查找其后与之值相同的所有元素,将它们删除;再对第二个元素做同样处理,依此类推。void delete(Seqlist *A)i=0;while(ilast)/*将第i个元素以后与其值相同的元素删除*/k=i+1;while(klast&A-datai=A-datak)k+;/*使k指向第一个与Ai不同的元素*/n=k-i-1;/*n表示要
5、删除元素的个数*/for(j=k;jlast;j+)A-dataj-n=A-dataj; /*删除多余元素*/A-last= A-last -n; i+;3写一个算法,从一个给定的顺序表A中删除值在xy(xdatai是否介于x和y之间,若是,并不立即删除,而是用n记录删除时应前移元素的位移量;若不是,则将A-datai向前移动n位。n用来记录当前已删除元素的个数。void delete(Seqlist *A,int x,int y)i=0;n=0;while (ilast)if (A-datai=x & A-dataidatai 介于x和y之间,n自增*/else A-datai-n=A-da
6、tai;/*否则向前移动A-datai*/i+;A-last-=n;4线性表中有n个元素,每个元素是一个字符,现存于向量Rn中,试写一算法,使R中的字符按字母字符、数字字符和其它字符的顺序排列。要求利用原来的存储空间,元素移动次数最小。【提示】对线性表进行两次扫描,第一次将所有的字母放在前面,第二次将所有的数字放在字母之后,其它字符之前。int fch(char c)/*判断c是否字母*/if(c=a&c=A&c=0&c=9) return (1);else return (0);void process(char Rn)low=0;high=n-1;while(lowhigh)/*将字母放在
7、前面*/while(lowhigh&fch(Rlow) low+;while(lowhigh&!fch(Rhigh) high-;if(lowhigh)k=Rlow;Rlow=Rhigh;Rhigh=k;low=low+1; high=n-1;while(lowhigh)/*将数字放在字母后面,其它字符前面*/while(lowhigh&fnum(Rlow) low+;while(lowhigh&!fnum(Rhigh) high-;if(lowhigh) k=Rlow;Rlow=Rhigh;Rhigh=k;5线性表用顺序存储,设计一个算法,用尽可能少的辅助存储空间将顺序表中前m个元素和后n个
8、元素进行整体互换。即将线性表:(a1, a2, , am, b1, b2, , bn)改变为:(b1, b2, , bn , a1, a2, , am)。【提示】比较m和n的大小,若mn,则将表中元素依次前移m次;否则,将表中元素依次后移n次。void process(Seqlist *L,int m,int n) if(m=n) for(i=1;idata0;for(k=1;klast;k+)L-datak-1=L-datak;L-dataL-last=x;else for(i=1;idataL-last;for(k=L-last-1;k=0;k- -)L-datak+1=L-datak;L
9、-data0=x;6已知带头结点的单链表L中的结点是按整数值递增排列的,试写一算法,将值为x 的结点插入到表L中,使得L仍然递增有序,并且分析算法的时间复杂度。LinkList insert(LinkList L, int x) p=L; while(p-next & xp-next-data) p=p-next;/*寻找插入位置*/ s=(LNode *)malloc(sizeof(LNode);/*申请结点空间*/s-data=x; /*填装结点*/s-next=p-next; p-next=s; /*将结点插入到链表中*/ return(L); 7假设有两个已排序(递增)的单链表A和B,
10、编写算法将它们合并成一个链表C而不改变其排序性。LinkList Combine(LinkList A, LinkList B)C=A;rc=C;pa=A-next;/*pa指向表A的第一个结点*/pb=B-next;/*pb指向表B的第一个结点*/free(B);/*释放B的头结点*/while (pa & pb)/*将pa、pb所指向结点中,值较小的一个插入到链表C的表尾*/ if(pa-datadata) rc-next=pa;rc=pa;pa=pa-next;elserc-next=pb;rc=pb;pb=pb-next;if(pa)rc-next=pa;elserc-next=pb;
11、/*将链表A或B中剩余的部分链接到链表C的表尾*/return(C);8假设长度大于1的循环单链表中,既无头结点也无头指针,p为指向该链表中某一结点的指针,编写算法删除该结点的前驱结点。【提示】利用循环单链表的特点,通过s指针可循环找到其前驱结点p及p的前驱结点q,然后可删除结点*p。viod delepre(LNode *s)LNode *p, *q;p=s;while (p-next!=s)q=p; p=p-next;q-next=s;free(p);9已知两个单链表A和B分别表示两个集合,其元素递增排列,编写算法求出A和B的交集C,要求C同样以元素递增的单链表形式存储。【提示】交集指的是
12、两个单链表的元素值相同的结点的集合,为了操作方便,先让单链表C带有一个头结点,最后将其删除掉。算法中指针p用来指向A中的当前结点,指针q用来指向B中的当前结点,将其值进行比较,两者相等时,属于交集中的一个元素,两者不等时,将其较小者跳过,继续后面的比较。LinkList Intersect(LinkList A, LinkList B)LNode *q, *p, *r, *s; LinkList C;C= (LNode *)malloc(sizeof(LNode);C-next=NULL;r=C;p=A; q=B;while (p & q ) if (p-datadata) p=p-next;
13、 elseif (p-data=q-data) s=(LNode *)malloc(sizeof(LNode); s-data=p-data; r-next=s; r=s; p=p-next; q=q-next; else q=q-next;r-next=NULL; C=C-next; return C;10设有一个双向链表,每个结点中除有prior、data和next域外,还有一个访问频度freq域,在链表被起用之前,该域的值初始化为零。每当在链表进行一次Locata(L,x)运算后,令值为x的结点中的freq域增1,并调整表中结点的次序,使其按访问频度的非递增序列排列,以便使频繁访问的结点
14、总是靠近表头。试写一个满足上述要求的Locata(L,x)算法。【提示】在定位操作的同时,需要调整链表中结点的次序:每次进行定位操作后,要查看所查找结点的freq域,将其同前面结点的freq域进行比较,同时进行结点次序的调整。typedef struct dnodedatatype data;int freq;struct DLnode *prior,*next;DLnode,*DLinkList;DlinkList Locate(DLinkList L, datatype x)p=L-next;while(p&p-data!=x) p=p-next; /*查找值为x的结点,使p指向它*/if
15、(!p) return(NULL);/*若查找失败,返回空指针*/p-freq+;/*修改p的freq域*/while(p-prior!=L&p-prior-freqfreq)/*调整结点的次序*/ k=p-prior-data;p-prior-data=p-data;p-data=k;k=p-prior-freq;p-prior-freq=p-freq;p-freq=k;p=p-prior; return(p);/*返回找到的结点的地址*/3.3 课后习题解答 #3.3.1 选择题1向一个栈顶指针为Top的链栈中插入一个p所指结点时,其操作步骤为(C)。ATop-next=p; Bp-nex
16、t=Top-next;Top-next=p;Cp-next=Top;Top=p; Dp-next=Top;Top=Top-next;2对于栈操作数据的原则是(B)。A先进先出 B后进先出 C后进后出 D不分顺序3若已知一个栈的入栈序列是1,2,3,n,其输出序列为p1,p2,p3,pN,若pN是n,则pi是(D)。Ai Bn-i C n-i+1 D不确定4表达式a*(bc)d的后缀表达式是(B)。Aabcd*-+ Babc-*d+ Cabc*-d+ D+-*abcd5采用顺序存储的两个栈共享空间S1.m,topi代表第i个栈( i=1,2)的栈顶,栈1的底在S1,栈2的底在Sm,则栈满的条件是
17、(B)。Atop2-top1|=0 Btop1+1=top2Ctop1+top2=m Dtop1=top26一个栈的入栈序列是a,b,c,d,e,则栈的不可能的输出序列是(C)。A edcba B decba Cdceab D abcde7在一个链队列中,若f,r分别为队首、队尾指针,则插入s所指结点的操作为(B)。Af-next=r;f=s; Br-next=s;r=s; Cs-next=r;r=s; Ds-next=f;f=s;8用不带头结点的单链表存储队列时,在进行删除运算时(D)。A仅修改头指针 B仅修改尾指针C头、尾指针都要修改 D头、尾指针可能都要修改9递归过程或函数调用时,处理参
18、数及返回地址,要用一种称为(C)的数据结构。A队列 B静态链表 C栈 D顺序表10栈和队都是(C)。A顺序存储的线性结构 B链式存储的非线性结构C限制存取点的线性结构 D限制存取点的非线性结构3.3.2 判断题1栈和队列的存储,既可以采用顺序存储结构,又可以采用链式存储结构。()2任何一个递归过程都可以转换成非递归过程。()3若输入序列为1,2,3,4,5,6,则通过一个栈可以输出序列3,2,5,6,4,1。()4通常使用队列来处理函数的调用。()5循环队列通常用指针来实现队列的头尾相接。()3.3.3 简答题1循环队列的优点是什么?如何判别它的空和满?循环队列的优点是能够克服“假溢满”现象。
19、设有循环队列sq,队满的判别条件为:(sq-rear+1)%maxsize=sq-front;或sq-num=maxsize。队空的判别条件为:sq-rear=sq-front。2栈和队列数据结构各有什么特点,什么情况下用到栈,什么情况下用到队列?栈和队列都是操作受限的线性表,栈的运算规则是“后进先出”,队列的运算规则是“先进先出”。栈的应用如数制转换、递归算法的实现等,队列的应用如树的层次遍历等。3什么是递归?递归程序有什么优缺点?一个函数在结束本函数之前,直接或间接调用函数自身,称为递归。例如,函数f在执行中,又调用函数f自身,这称为直接递归;若函数f在执行中,调用函数g,而g在执行中,又
20、调用函数f,这称为间接递归。在实际应用中,多为直接递归,也常简称为递归。递归程序的优点是程序结构简单、清晰,易证明其正确性。缺点是执行中占内存空间较多,运行效率低。4设有编号为1,2,3,4的四辆车,顺序进入一个栈式结构的站台,试写出这四辆车开出车站的所有可能的顺序(每辆车可能入站,可能不入站,时间也可能不等)。1234,1243,1324,1342,1432,213,2143,2314,2341,2431,3214,3241,3421,43214.3 课后习题解答#4.3.1 选择题1下面关于串的叙述错误的是(C)。A串是字符的有限序列 B串既可以采用顺序存储,也可以采用链式存储C空串是由空
21、格构成的串 D模式匹配是串的一种重要运算2串的长度是指(B)。A串中所含不同字母的个数 B串中所含字符的个数C串中所含不同字符的个数 D串中所含非空格字符的个数3已知串S=aaab,其Next数组值为(D)。A0123 B1123 C1231 D12114二维数组M的成员是6个字符(每个字符占一个存储单元)组成的串,行下标i的范围从0到8,列下标j的范围从1到10,则存放M至少需要(D)个字节;M的第8列和第5行共占(A)个字节;若M按行优先方式存储,元素M85的起始地址与当M按列优先方式存储时的(C)元素的起始地址一致。(1)A90 B180 C240 D540(2)A108 B114 C5
22、4 D60(3)AM85 BM310 CM58 DM095数组A中,每个元素的存储占3个单元,行下标i从1到8,列下标j从1到10,从首地址SA开始连续存放在存储器内,存放该数组至少需要的单元个数是(C),若该数组按行存放,元素A85的起始地址是(C),若该数组按列存放,元素A85的起始地址是(C)。(1)A80 B100 C240 D270(2)ASA+141 BSA+144 CSA+222 DSA+225(3)ASA+141 BSA+180 CSA+117 DSA+2256稀疏矩阵采用压缩存储,一般有(C)两种方法。A二维数组和三维数组 B三元组和散列C三元组表和十字链表 D散列和十字链表
23、4.3.2 判断题1串相等是指两个串的长度相等。()2KMP算法的特点是在模式匹配时指示主串的指针不会变小。()3稀疏矩阵压缩存储后,必会失去随机存取功能。()4数组是线性结构的一种推广,因此与线性表一样,可以对它进行插入,删除等操作。()5若采用三元组存储稀疏矩阵,把每个元素的行下标和列下标互换,就完成了对该矩阵的转置运算。()6若一个广义表的表头为空表,则此广义表亦为空表。()7所谓取广义表的表尾就是返回广义表中最后一个元素。()4.3.3 简答题1KMP算法较朴素的模式匹配算法有哪些改进?KMP算法主要优点是主串指针不回溯。当主串很大不能一次读入内存且经常发生部分匹配时,KMP算法的优点
24、更为突出。2设字符串S=aabaabaabaac,P=aabaac。(1)给出S和P的next值和nextval值; (2)若S作主串,P作模式串,试给出利用KMP算法的匹配过程。【解答】 (1)S的next与nextval值分别为012123456789和002002002009,p的next与nextval值分别为012123和002003。 (2)利用BF算法的匹配过程: 利用KMP算法的匹配过程: 第一趟匹配:aabaabaabaac 第一趟匹配:aabaabaabaac aabaac(i=6,j=6) aabaac(i=6,j=6) 第二趟匹配:aabaabaabaac 第二趟匹配:
25、aabaabaabaac aa(i=3,j=2) (aa)baac 第三趟匹配:aabaabaabaac 第三趟匹配:aabaabaabaac a(i=3,j=1) (成功) (aa)baac第四趟匹配:aabaabaabaac aabaac(i=9,j=6)第五趟匹配:aabaabaabaac aa(i=6,j=2)第六趟匹配:aabaabaabaac a(i=6,j=1)第七趟匹配:aabaabaabaac(成功) aabaac(i=13,j=7)3假设按行优先存储整数数组A9358时,第一个元素的字节地址是100,每个整数占个字节。问下列元素的存储地址是什么?(1) a0000 (2)a
26、1111 (3)a3125 (4)a8247【解答】(1) LOC( a0000)= 100 (2) LOC( a1111)=100+(3*5*8*1+5*8*1+8*1+1)*4=776 (3) LOC( a3125)=100+(3*5*8*3+5*8*1+8*2+5) *4=1784 (4) LOC( a8247)= 100+(3*5*8*8+5*8*2+8*4+7) *4=48164假设一个准对角矩阵:a11 a12a21 a22a33 a34a43 a44 . aij a2m-1,2m-1 a2m-1,2m a2m,2m-1 a2m,2m 按以下方式存储于一维数组B4m中(m为一个整数
27、):012345 6 k 4m-1 4ma 11a 12a21a22a33a34a43aija2m-1,2ma2m,2m-1a2m,2m写出下标转换函数k=f(i,j)。【解答】由题目可知,每一行有两个非0元素。当i为奇数时,第i行的元素为:ai,i、ai,(i+1),此时k=2*(i-1)+j-i=i+j-2当i为偶数时,第i行的元素为:ai,(i-1)、ai,i,此时k=2*(i-1)+j-I+1=i+j-1综上所述,k=i+j-i%2-1。5设有nn的带宽为3的带状矩阵A,将其3条对角线上的元素存于数组B3n中,使得元素Buv=aij,试推导出从(i,j)到 (u,v)的下标变换公式。【
28、解答】u=j-i+1v=j-16现有如下的稀疏矩阵A(如图所示),要求画出以下各种表示方法。(1)三元组表表示法(2)十字链表法。0 0 0 22 0 -150 13 3 0 0 00 0 0 -6 0 00 0 0 0 0 091 0 0 0 0 00 0 28 0 0 0【解答】(1)三元组表表示法:i j v12345671 4 221 6 -152 2 132 3 33 4 -65 1 916 3 28(2)十字链表法:012345012345519123334-61422632816-1522137画出下列广义表的头尾表示存储结构示意图。(1)A=(a,b,c),d,(a,b,c)(
29、2)B=(a,(b,(c,d),e),f)(1)11111 1 1 d0 a1 b1 c(2)1111 1 1 0 f0 a0 b0 c1 10 c0 d5.3 课后习题解答 5.3.1 选择题1下列说法正确的是(C)。A二叉树中任何一个结点的度都为2 B二叉树的度为2C一棵二叉树的度可小于2 D任何一棵二叉树中至少有一个结点的度为22以二叉链表作为二叉树的存储结构,在具有n个结点的二叉链表中(n0),空链域的个数为(C)。A2n-1 Bn-1 Cn+1 D2n+13线索化二叉树中,某结点*p没有孩子的充要条件是(B)。Ap-lchild=NULL Bp-ltag=1且p-rtag=1Cp-l
30、tag=0 Dp-lchild=NULL 且p-ltag=14如果结点A有3个兄弟,而且B是A的双亲,则B的度是(B)。 A3 B4 C5 D1 5某二叉树T有n个结点,设按某种顺序对T中的每个结点进行编号,编号值为1,2,.n。且有如下性质:T中任意结点v,其编号等于左子树上的最小编号减,而v的右子树的结点中,其最小编号等于v左子树上结点的最大编号加,这是按(B)编号的。A 中序遍历序列 B 先序遍历序列 C 后序遍历序列 D 层次顺序 6设F是一个森林,B是由F转换得到的二叉树,F中有n个非终端结点,B中右指针域为空的结点有(C)个。An-1 B n C n+1 Dn+2 7一棵完全二叉树
31、上有1001个结点,其中叶子结点的个数是(B)。A 500 B 501 C490 D4958设森林F中有三棵树,第一,第二,第三棵树的结点个数分别为N1,N2和N3。与森林F对应的二叉树根结点的右子树上的结点个数是(D)。AN1 BN1+N2 CN2 DN2+N39任何一棵二叉树的叶结点在先序、中序、后序遍历序列中的相对次序(A)。A不发生改变 B 发生改变 C 不能确定 D 以上都不对10若一棵二叉树的后序遍历序列为dabec,中序遍历序列为debac,则先序遍历序列为(D)。Acbed Bdecab Cdeabc Dcedba11若一棵二叉树的先序遍历序列为abdgcefh,中序遍历的序列
32、为dgbaechf,则后序遍历的结果为(D)。 A gcefha B gdbecfha C bdgaechf D gdbehfca12一棵非空二叉树的先序遍历序列与后序遍历序列正好相反,则该二叉树一定满足(AB)。A所有的结点均无左孩子 B所有的结点均无右孩子C只有一个叶子结点 D是一棵满二叉树13引入线索二叉树的目的是(A)。A加快查找结点的前驱或后继的速度 B为了能在二叉树中方便的进行插入与删除C为了能方便的找到双亲 D使二叉树的遍历结果唯一 14设高度为h的二叉树上只有度为和度为的结点,则此类二叉树中所包含的结点数至少为(B)。A2*h B 2*h-1 C 2*h+1 Dh+115一个具
33、有567个结点的二叉树的高h为(D)。A9 B10 C9至566之间 D10至567之间16给一个整数集合3,5,6,7,9,与该整数集合对应的哈夫曼树是(B)。A B C D93765 3567979536765395.3.2 判断题1二叉树是树的特殊形式。()2由树转换成二叉树,其根结点的右子树总是空的。()3先根遍历一棵树和先序遍历与该树对应的二叉树,其结果不同。()4先根遍历森林和先序遍历与该森林对应的二叉树,其结果不同。()5完全二叉树中,若一个结点没有左孩子,则它必是叶子。()6对于有N个结点的二叉树,其高度为log2N1。()7若一个结点是某二叉树子树的中序遍历序列中的最后一个结
34、点,则它必是该子树的先序遍历序列中的最后一个结点。()8若一个结点是某二叉树子树的中序遍历序列中的第一个结点,则它必是该子树的后序遍历序列中的第一个结点。()9不使用递归也可实现二叉树的先序、中序和后序遍历。()10先序遍历二叉树的序列中,任何结点的子树的所有结点不一定跟在该结点之后。()11先序和中序遍历用线索树方式存储的二叉树,不必使用栈。()12在后序线索二叉树中,在任何情况下都能够很方便地找到任意结点的后继。()13哈夫曼树是带权路径长度最短的树,路径上权值较大的结点离根较近。()14在哈夫曼编码中,出现频率相同的字符编码长度也一定相同。()15用一维数组存放二叉树时,总是以先序遍历存
35、储结点。()16由先序序列和后序序列能唯一确定一棵二叉树。()17由先序序列和中序序列能唯一确定一棵二叉树。()18对一棵二叉树进行层次遍历时,应借助于一个栈。()19完全二叉树可采用顺序存储结构实现存储,非完全二叉树则不能。()20满二叉树一定是完全二叉树,反之未必。()5.3.3 简答题1一棵度为2的树与一棵二叉树有何区别?树与二叉树之间有何区别?【解答】二叉树是有序树,度为2的树是无序树,二叉树的度不一定是2。ADBGEHCF(图 1)二叉树是有序树,每个结点最多有两棵子树,树是无序树,且每个结点可以有多棵子树。2对于图1所示二叉树,试给出:(1)它的顺序存储结构示意图;(2)它的二叉链
36、表存储结构示意图;(3)它的三叉链表存储结构示意图。【解答】(1)顺序存储结构示意图:ABCDEFGH(2)二叉链表存储结构示意图: (3)三叉链表存储结构示意图:ABC D E F G H A BC D E F G H IDEFGCBANMKJH(图 2)3对于图2所示的树,试给出:(1)双亲数组表示法示意图;(2)孩子链表表示法示意图;(3)孩子兄弟链表表示法示意图。【解答】(1)双亲数组表示法示意图: (2)孩子链表表示法示意图:0A-11B02C03D24E25F16G17H58I29J410K411M312N82 6410 15311 97 12 0A1B2C3D4E5F6G7H8I9J10K11M12N8 (3)孩子兄弟链表表示法示意图:A B N H C GF EDI