计算机考研资料-算法设计题.pdf
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《计算机考研资料-算法设计题.pdf》由会员分享,可在线阅读,更多相关《计算机考研资料-算法设计题.pdf(189页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、目录 线性表算法设计题答案.1 栈和队列算法设计题答案.40 串算法设计题答案.55 数组和广义表算法设计题答案.65 树和二叉树算法设计题答案.80 图算法设计题答案.124 集合算法设计题答案.151 排序算法设计题答案.171彼 性 装 算法设计题答案L 题目分析 因为两链表已按元素值递增次序排列,将其合并时,均从第一个结点起进行比较,将小的链入链表中,同时后移链表工作指针。该问题要求结果链表按元素值递减次序排列。故在合并的同时,将链表结点逆置。LinkedList Union(LinkedList la,lb)/71a,lb分别是带头结点的两个单链表的头指针,链表中的元素值按递增序排列
2、,本算法将两链表合并成一个按元素值递减次序排列的单链表。pa=la-next;pb=lb-next;/pa,pb 分别是链表 la 和 1b 的工作指针la-next=null;1a 作结果链表的头指针,先将结果链表初始化为空。while(pa!=null&pb!=null)当两链表均不为空时作if(pa-datadata)r=pa-next;将p a 的后继结点暂存于r。pa-next=la-next;将pa结点链于结果表中,同时逆置。la-next=pa;pa=r;恢复p a 为当前待比较结点。elser=pb-next;/将 p b 的后继结点暂存于r。pb-next=la-next;将
3、pb结点链于结果表中,同时逆置。la-next=pb;pb=r;恢复p b 为当前待比较结点。)while(pa!=null)将la表的剩余部分链入结果表,并逆置。r=pa-next;pa-next=la-next;la-next=pa;pa=r;while(pb!=null)r=pb-next;pb-next=la-next;la-next=pb;pb=r;/算法Union结束。算法讨论上面两链表均不为空的表达式也可简写为while(pa&pb),两递增有序表合并成递减有序表时,上述算法是边合并边逆置。也可先合并完,再作链表逆置。后者不如前者优化。算法中最后两个while语句,不可能执行两个
4、,只能二者取一,即哪个表尚未到尾,就将其逆置到结果表中,即将剩余结点依次前插入到结果表的头结点后面。与本题类似的其它题解答如下:(1)问题分析与上题类似,不同之处在于:一是链表无头结点,为处理方便,给加上头结点,处理结束再删除之;二是数据相同的结点,不合并到结果链表中;三 是 hb链表不能被破坏,即将h b 的结点合并到结果链表时,要生成新结点。LinkedList Union(LinkedList ha,hb)ha和 hb是两个无头结点的数据域值递增有序的单链表,本算法将h b 中并不出现在h a 中的数据合并到ha中,合并中不能破坏hb链表。LinkedList la;la=(Linked
5、List)malloc(sizeof(LNode);la-next=ha;/申请头结点,以便操作。pa=ha;pa是 ha链表的工作指针pb=hb;pb是 hb链表的工作指针pre=la;/pre指向当前待合并结点的前驱。while(pa&pb)if(pa-datadata)/处理 ha 中数据pre-next=pa;pre=pa;pa=pa-next;else if(pa-datapb-data)处理 hb 中数据。r=(LinkedList)malloc(sizeof(LNode);/申请空间r-data=pb-data;pre-next=r;pre=r;将新结点链入结果链表。pb=pb-
6、next;hb链表中工作指针后移。else/处理 pa-data=pb-data;pre-next=pa;pre=pa;pa=pa-next;两结点数据相等时,只将ha的数据链入。pb=pb-next;不要h b 的相等数据if(pa!=null)pre-next=pa;将两链表中剩余部分链入结果链表。else pre-next=pb;free(la);释放头结点.ha,hb指针未被破坏。算法nion结束。(2)本题与上面两题类似,要求结果指针为1c,其核心语句段如下:pa=la-next;pb=hb-next;lc=(LinkedList)malloc(sizeof(LNode);pc=lc
7、;pc是结果链表中当前结点的前驱while(pa&pb)if(pa-datadata)pc-next=pa;pc=pa;pa=pa-next;else pc-next=pb;pc=pb;pb=pb-next;if(pa)pc-next=pa;else pc-next=pb;free(la);free(lb);释放原来两链表的头结点。算法时间复杂度为0(m+n),其中m 和 n 分别为链表la和 1b的长度。2.题目分析 本组题有6 个,本质上都是链表的合并操作,合并中有各种条件。与前组题不同的是,叙述上是用线性表代表集合,而操作则是求集合的并、交、差(AUB,AAB,A-B)等。本题与上面1.
8、(2)基本相同,不同之处1.(2)中链表是“非递减有序”,(可能包含相等元素),本题是元 素“递增有序”(不准有相同元素)。因此两表中合并时,如有元素值相等元素,则应删掉一个。LinkedList Union(LinkedList ha,hb)线性表A 和 B 代表两个集合,以链式存储结构存储,元素递增有序。ha和 hb分别是其链表的头指针。本算法求A 和 B 的并集A U B,仍用线性表表示,结果链表元素也是递增有序。pa=ha-next;pb=hb-next;设工作指针 pa 和 pb。pc=ha;pc为结果链表当前结点的前驱指针。while(pa&pb)if(pa-datadata)pc
9、-next=pa;pc=pa;pa=pa-next;else if(pa-datapb-data)pc-next=pb;pc=pb;pb=pb-next;else/7处理 pa-data=pb-data.pc-next=pa;pc=pa;pa=pa-next;u=pb;pb=pb-next;free(u);if(pa)pc-next=pa;/若 ha表未空,则链入结果表。else pc-next=pb;若hb表未空,则链入结果表。free(hb);释放hb头结点return(ha);算法Union结束。与本题类似的其它几个题解答如下:(1)解答完全同上2。(2)本题是求交集,即只有同时出现在两
10、集合中的元素才出现在结果表中。其核心语句段如下:pa=la-next;pb=lb-next;设工作指针 pa 和 pb;pc=la;结果表中当前合并结点的前驱的指针。while(pa&pb)if(pa-data=pb-data)交集并入结果表中。pc-next=pa;pc=pa;pa=pa-next;u=pb;pb=pb-next;free(u);else if(pa-datadata)u=pa;pa=pa-next;free(u);else u=pb;pb=pb-next;free(u);while(pa)u=pa;pa=pa-next;free(u);/释放结点空间while(pb)u=p
11、b;pb=pb-next;f ree(u);释放结点空间pc-next=null;置链表尾标记。free(1b);注:本算法中也可对B 表不作释放空间的处理(3)本题基本与(2)相同,但要求无重复元素,故在算法中,待合并结点数据要与其前驱比较,只有在与前驱数据不同时才并入链表。其核心语句段如下。pa=Ll-next;pb=L2-next;pa、pb 是两链表的工作指针。pc=Ll;/L1作结果链表的头指针。while(pa&pb)if(pa-datadata)u=pa;pa=pa-next;free(u);/册!j 除 LI 表多余元素else if(pa-datapb-data)pb=pb-
12、next;pb 指针后移else 处理交集元素if(pc=Ll)pc-next=pa;pc=pa;pa=pa-next;处理第一个相等的元素。else if(pc-data=pa-data)u=pa;pa=pa-next;free(u);重复元素不进入LI表。else pc-next=pa;pc=pa;pa=pa-next;交集元素并入结果表。/whilewhile(pa)u=pa;pa=pa-next;free(u);/册 LI 表乘余元素pc-next=null;/置结果链表尾。注:本算法中对L2表未作释放空间的处理。(4)本题与上面(3)算法相同,只是结果表要另辟空间。(5)题目分析 本
13、题首先求B 和 C 的交集,即求B 和 C 中共有元素,再与A 求并集,同时删除重复元素,以保持结果A 递增。LinkedList union(LinkedList A,B,C)A,B和 C 均是带头结点的递增有序的单链表,本算法实现A=AU(BPC),使求解结构保持递增有序。pa=A-next;pb=B-next;pc=C-next;/设置三个工作指针。pre=A;/pre指向结果链表中当前待合并结点的前驱。if(pa-datadata I I pa-datadata)A 中第一个元素为结果表的第一元素。pre-next=pa;pre=pa;pa=pa-next;else jwhile(pb
14、&pc)找B 表和C 表中第一个公共元素。i f(pb-datadata)pb=pb-next;else i f(pb-datapc-data)pc=pc-next;else break;找至I B 表 和 C 表的共同元素就退出while循环。if(pb&pc)/因共同元素而非B 表或C 表空而退出匕面while循环。if(pa-datapb-data)A 表当前元素值大于B 表和C 表的公共元素,先将B 表元素链入。pre-next=pb;pre=pb;pb=pb-next;pc=pc-next;B,C 公共兀素为结果表第一兀素。结束了结果表中第一元素的确定while(pa&pb&pc)w
15、hile(pb&pc)if(pb-datadata)pb=pb-next;else if(pb-datapc-data)pc=pc-next;else break;B 表和C 表有公共元素。if(pb&pc)while(pa&pa-datadata)/先将A 中小于B,C 公共元素部分链入。pre-next=pa;pre=pa;pa=pa-next;if(pre-data!=pb-data)pre-next=pb;pre=pb;pb=pb-next;pc=pc-next;elsepb=pb-next;pc=pc-next;/若 A 中已有.B,C 公共元素,则不再存入结果表。/while(pa
16、&pb&pc)if(pa)pre-next=pa;当B,C 无公共元素(即一个表已空),将 A 中剩余链入。算法Union结束 算法讨论 本算法先找结果链表的第个元素,这是因为题目要求结果表要递增有序(即删除重复元素)。这就要求当前待合并到结果表的元素要与其前驱比较。由于初始pre=A(头结点的头指针),这时的data域无意义,不能与后继比较元素大小,因此就需要确定第一个元素。当然,不要这样作,而直接进入下面循环也可以,但在链入结点时,必须先判断pre是否等于A,这占用了过多的时间。因此先将第一结点链入是可取的。算法中的第二个问题是要求时间复杂度为O(|A|+|B|+|C|)。这就要求各个表的
17、工作指针只能后移(即不能每次都从头指针开始查找)。本算法满足这一要求。最后一个问题是,当 B,C 有一表为空(即B 和 C 已无公共元素时),要将A 的剩余部分链入结果表。3.题目分析 循环单链表L1和 L2数据结点个数分别为m 和 n,将二者合成一个循环单链表时,需要将个循环链表的结点(从第一元素结点到最后个结点)插入到另一-循环链表的第一元素结点前即可。题目要求“用最快速度将两表合并“,因此应找结点个数少的链表查其尾结点。LinkedList Union(LinkedList LIf L2;int m,n)L1和 L2分别是两循环单链表的头结点的指针,m 和 n 分别是L1和 L2的长度。
18、本算法用最快速度将L1和 L2合并成个循环单链表。if(m0|n0)printf(“表长输入错误n);exit(0);)if(mn)若mnext!=L1)p=p-next;查最后一个元素结点。p-next=L2-next;将L1循环单链表的元素结点插入到L2的第一元素结点前。L2-next=Ll-next;free(LI);释放无用头结点。处理完m n 情况e l s e 下面处理L2长度小于等于L1的情况 if(n=0)return(LI);/L2 为空表。elsep=L2;while(p-next!=L2)p=p-next;查最后元素结点。p-next=Ll-next;将L2的元素结点插入
19、到L1循环单链表的第一元素结点前。Ll-next=L2-next;free(L2);释放无用头结点。算法结束。类似本题叙述的其它题解答如F:(1)题目分析 本题将线性表1a和 1b连接,要求时间复杂度为0(1),且占用辅助空间尽量小。应该使用只设尾指针的单循环链表。LinkedList Union(LinkedList la,lb)la和 lb是两个无头结点的循环单链表的尾指针,本算法将1b接 在 la后,成为一个单循环链表。q=la-next;q 指 向 la的第一个元素结点。la-next=lb-next;将1b的最后元素结点接到1b的第一元素。lb-next=q;将1b指 向 la的第一
20、元素结点,实现了 1b接 在 la后。return(1b);返回结果单循环链表的尾指针1b。算法结束。算法讨论 若循环单链表带有头结点,则相应算法片段如下:q=lb-next;q 指向1b的头结点;lb-next=la-next;/71b的后继结点为la的头结点。la-next=q-next;la的后继结点为1b的第一元素结点。free(q);释放lb的头结点return(1b);返回结果单循环链表的尾指针lb(2)题目分析 本题要求将单向链表ha和单向循环链表hb合并成一个单向链表,要求算法所需时间与链表长度无关,只有使用带尾指针的循环单链表,这样最容易找到链表的首、尾结点,将该结点序列插入
21、到单向链表第一元素之前即可。其核心算法片段如下(设两链表均有头结点)q=hb-next;单向循环链表的表头指针hb-next=ha-next;将循环单链表最后元素结点接在ha第一元素前。ha-next=q-next;将指向原单链表第一元素的指针指向循环单链表第一结点free(q);释放循环链表头结点。若两链表均不带头结点,则算法片段如下:q=hb-next;q 指向h b 首元结点。hb-next=ha;hb尾结点的后继是ha第一元素结点。ha=q;头指针指向hb的首元结点。4.题目分析 顺序存储结构的线性表的插入,其时间复杂度为0(n),平均移动近一半的元素。线性表L A 和 L B 合并时
22、,若从第个元素开始,一定会造成元素后移,这不符合本题“高效算法”的要求。另外,题中叙述“线性表空间足够大”也暗示出另外合并方式,即应从线性表的最后一个元素开始比较,大者放到最终位置上。设两线性表的长度各为m 和 n,则结果表的最后一个元素应在m+n位置上。这样从后向前,直到第 个元素为止。PROC Union(VAR LA:SeqList;LB:SeqList)LA和 LB是顺序存储的非递减有序线性表,本算法将LB合并到LA中,元素仍非递减有序。m:=LA.last;n:=LB.last;/m,n 分别为线性表 LA 和 LB 的长度。k:=m+n;k 为结果线性表的工作指针(下标)。i:=m
23、;j :=n;/i,j 分别为线性表LA和 LB的工作指针(下标)。WHILE(i0)AND(j0)DOIF LA.elem i=LB.elem jTHENLA.elemk:=LA.elemi;k:=k-l;i:=i-l;ELSELA.elemk:=LB.elemj;k:=k-l;j:=j-1;WHILE(j0)DO LA.elemk:=LB.elemj;k:=k-l;j:=j-l;LA.last:=m+n;ENDP;算法讨论 算法中数据移动是主要操作。在最佳情况下(LB的最小元素大于LA的最大元素),仅将LB的n 个元素移(拷贝)到LA中,时间复杂度为0(n),最差情况,LA的所有元素都要移
24、动,时间复杂度为0(m+n)。因数据合并到LA中,所以在退出第一个WHILE循环后,只需要一个WHILE循环,处理L B 中剩余元素。第二个循环只有在LB有剩余元素时才执行,而 在 L A 有剩余元素时不执行。本算法利用了题目中“线性表空间足够大”的条件,“最大限度的避免移动元素”,是“种高效算法”。5.题目分析本题实质上是一个排序问题,要求 不得使用除该链表结点以外的任何链结点空间”。链表.上的排序采用直接插入排序比较方便,即首先假定第一个结点有序,然后,从第二个结点开始,依次插入到前面有序链表中,最终达到整个链表有序。LinkedList LinkListSort(LinkedList l
25、ist)list是不带头结点的线性链表,链表结点构造为data和 link两个域,data是数据域,link是指针域。本算法将该链表按结点数据域的值的大小,从小到大重新链接。p=list-link;p 是工作指针,指向待排序的当前元素。list-link=null;假定第一个元素有序,即链表中现只有一个结点。while(p!=null)r=p-link;r 是 p 的后继。q=list;if(q-datap-data)处理待排序结点p 比第个元素结点小的情况。p-link=list;list=p;链表指针指向最小元素。else 查找元素值最小的结点。while(q-link!=null&q-l
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 考研 资料 算法 设计
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内