数据结构考研复习题--第二章--线性表(带答案)

更新时间:2024-05-26 16:53:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第2章 线性表

一 选择题

1.下述哪一条是顺序存储结构的优点?( )【北方交通大学 2001 一、4(2分)】 A.存储密度大 B.插入运算方便 C.删除运算方便 D.可方便地用于各种逻辑结构的存储表示

2.下面关于线性表的叙述中,错误的是哪一个?( )【北方交通大学 2001 一、14(2分)】

A.线性表采用顺序存储,必须占用一片连续的存储单元。 B.线性表采用顺序存储,便于进行插入和删除操作。 C.线性表采用链接存储,不必占用一片连续的存储单元。 D.线性表采用链接存储,便于插入和删除操作。 3.线性表是具有n个( )的有限序列(n>0)。 【清华大学 1998 一、4(2分)】 A.表元素 B.字符 C.数据元素 D.数据项 E.信息项 4.若某线性表最常用的操作是存取任一指定序号的元素和在最后进行插入和删除运算,则利用( )存储方式最节省时间。【哈尔滨工业大学 2001 二、1(2分)】

A.顺序表 B.双链表 C.带头结点的双循环链表 D.单循环链表 5.某线性表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则采用( )存储方式最节省运算时间。【南开大学 2000 一、3】

A.单链表 B.仅有头指针的单循环链表 C.双链表 D.仅有尾指针的单循环链表

6.设一个链表最常用的操作是在末尾插入结点和删除尾结点,则选用( )最节省时间。

A. 单链表 B.单循环链表 C. 带尾指针的单循环链表 D.带头结点的双循环链表

【合肥工业大学 2000 一、1(2分)】

7.若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点。则采用( )存储方式最节省运算时间。【北京理工大学 2000 一、1(2分)】

A.单链表 B.双链表 C.单循环链表 D.带头结点的双循环链表 8. 静态链表中指针表示的是( ). 【北京理工大学 2001 六、2(2分)】 A. 内存地址 B.数组下标 C.下一元素地址 D.左、右孩子地址 9. 链表不具有的特点是( ) 【福州大学 1998 一、8 (2分)】 A.插入、删除不需要移动元素 B.可随机访问任一元素 C.不必事先估计存储空间 D.所需空间与线性长度成正比 10. 下面的叙述不正确的是( )【南京理工大学 1996 一、10(2分)】 A.线性表在链式存储时,查找第i个元素的时间同i的值成正比 B. 线性表在链式存储时,查找第i个元素的时间同i的值无关

C. 线性表在顺序存储时,查找第i个元素的时间同i 的值成正比 D. 线性表在顺序存储时,查找第i个元素的时间同i的值无关

11. 线性表的表元存储方式有((1))和链接两种。试指出下列各表中使用的是何种存储方式:表1是((2))存储方式;表2是((3))存储方式;表3是((4))存储方式;表

4是((5))存储方式。表左的s指向起始表元。 表元编号 1 2 货号 618 205 数量 40 2 表元间联系 2 3 3 4 5 6 表元编号 1 2 3 4 5 6 表元编号 1 2 3 4 5 6 表元编号 1 2 3 4 5 6 103 501 781 910 货号 618 205 103 501 781 910 货号 618 205 103 501 781 910 货号 618 205 103 501 781 910 15 20 17 24 数量 40 2 15 20 17 24 数量 40 2 15 20 17 24 数量 40 2 15 20 17 24 4 5 6 0 表元间联系 5 1 4 2 6 3 表元间联系 5 1 4 0 6 3 表元间联系 1 1 4 0 6 3 2 0 6 3 1 5 5 2

s→

表1 s→

表2

表3

s→

表4

s→

供选择的答案: A.连续 B.单向链接 C.双向链接 D.不连接 E.循环链接 F.树状 G.网状 H.随机 I.顺序 J.顺序循环

【上海海运学院 1995 二、1(5分)】

12.(1) 静态链表既有顺序存储的优点,又有动态链表的优点。所以,它存取表中第i个元

素的时间与i无关。

(2) 静态链表中能容纳的元素个数的最大数在表定义时就确定了,以后不能增加。 (3) 静态链表与动态链表在元素的插入、删除上类似,不需做元素的移动。

以上错误的是( )【南京理工大学 2000 一、3(1.5分)】 A.(1),(2) B.(1) C.(1),(2),(3) D.(2) 13. 若长度为n的线性表采用顺序存储结构,在其第i个位置插入一个新元素的算法的时间复杂度为( )(1<=i<=n+1)。【北京航空航天大学 1999 一、1(2分)】

2

A. O(0) B. O(1) C. O(n) D. O(n)

14. 对于顺序存储的线性表,访问结点和增加、删除结点的时间复杂度为( )。

A.O(n) O(n) B. O(n) O(1) C. O(1) O(n) D. O(1) O(1)

【青岛大学 2000 五、1(2分)】

15.线性表( a1,a2,?,an)以链接方式存储时,访问第i位置元素的时间复杂性为( )

A.O(i) B.O(1) C.O(n) D.O(i-1)【中山大学 1999 一、2】

16.非空的循环单链表head的尾结点p↑满足( )。【武汉大学 2000 二、10】

A.p↑.link=head B.p↑.link=NIL C.p=NIL D.p= head 17.循环链表H的尾结点P的特点是( )。【中山大学 1998 二、2(2分)】 A.P^.NEXT:=H B.P^.NEXT:= H^.NEXT C.P:=H D.P:=H^.NEXT 18.在一个以 h 为头的单循环链中,p 指针指向链尾的条件是()【南京理工大学1998 一、15(2分)】

A. p^.next=h B. p^.next=NIL C. p^.next.^next=h D. p^.data=-1 19.完成在双循环链表结点p之后插入s的操作是( );【北方交通大学 1999 一、4(3分)】

A. p^.next:=s ; s^.priou:=p; p^.next^.priou:=s ; s^.next:=p^.next; B. p^.next^.priou:=s; p^.next:=s; s^.priou:=p; s^.next:=p^.next; C. s^.priou:=p; s^.next:=p^.next; p^.next:=s; p^.next^.priou:=s ; D. s^.priou:=p; s^.next:=p^.next; p^.next^.priou:=s ; p^.next:=s; 20.在双向循环链表中,在p指针所指向的结点前插入一个指针q所指向的新结点,其修改指针的操作是( )。【北京邮电大学 1998 二、2(2分)】

注:双向链表的结点结构为(llink,data,rlink)。 供选择的答案:

A. p↑.llink:=q; q↑.rlink:=p; p↑.llink↑.rlink:=q; q↑.llink:=q;

B. p↑.llink:=q; p↑.llink↑.rlink:=q ; q↑.rlink:= p; q↑.llink:=p↑.llink;

C. q↑.rlink:=p; q↑.llink:=p↑.llink; p↑.llink↑.rlink:=q; p↑.llink:=q;

D. q↑.llink:=p↑.llink;q↑.rlink:=p; p↑.llink:=q;p↑.llink:=q;(编者按:原题如此)

21.在非空双向循环链表中q所指的结点前插入一个由p所指的链结点的过程依次为:

rlink(p) ← q; llink(p) ← llink(q); llink(q) ← p; ( )

A.rlink(q) ← p B.rlink(llink(q)) ← p C.rlink(llink(p)) ← p D.rlink(rlink(p)) ← p

【北京航空航天大学 2000 一、1(2分)】

22. 双向链表中有两个指针域,llink和rlink,分别指回前驱及后继,设p指向链表中的一个结点,q指向一待插入结点,现要求在p前插入q,则正确的插入为( )【南京理工大学1996 一、1(2分)】

A. p^.llink:=q; q^.rlink:=p; p^.llink^.rlink:=q; q^.llink:=p^.llink;

B. q^.llink:=p^.llink; p^.llink^.rlink:=q; q^.rlink:=p; p^.llink:=q^.rlink;

C. q^.rlink:=p; p^.rlink:=q; p^.llink^.rlink:=q; q^.rlink:=p;

D. p^.llink^.rlink:=q; q^.rlink:=p; q^.llink:=p^.llink; p^.llink:=q; 23.在双向链表指针p的结点前插入一个指针q的结点操作是( )。【青岛大学 2000 五、

2(2分)】

A. p->Llink=q;q->Rlink=p;p->Llink->Rlink=q;q->Llink=q;

B. p->Llink=q;p->Llink->Rlink=q;q->Rlink=p;q->Llink=p->Llink; C. q->Rlink=p;q->Llink=p->Llink;p->Llink->Rlink=q;p->Llink=q; D. q->Llink=p->Llink;q->Rlink=q;p->Llink=q;p->Llink=q;

24.在单链表指针为p的结点之后插入指针为s的结点,正确的操作是:( )。

A.p->next=s;s->next=p->next; B. s->next=p->next;p->next=s; C.p->next=s;p->next=s->next; D. p->next=s->next;p->next=s;

【青岛大学 2001 五、3(2分)】

25.对于一个头指针为head的带头结点的单链表,判定该表为空表的条件是( )

A.head==NULL B.head→next==NULL C.head→next==head D.head!=NULL

【北京工商大学 2001 一、5(3分)】

26. 在双向链表存储结构中,删除p所指的结点时须修改指针( )。

A. (p^.llink)^.rlink:=p^.rlink (p^.rlink)^.llink:=p^.llink; B. p^.llink:=(p^.llink)^.llink (p^.llink)^.rlink:=p;

C. (p^.rlink)^.llink:=p p^.rlink:=(p^.rlink)^.rlink D. p^.rlink:=(p^.llink)^.llink p^.llink:=(p^.rlink)^.rlink;

【西安电子科技大学 1998 一、1(2分)】

27. 双向链表中有两个指针域,llink和rlink分别指向前趋及后继,设p指向链表中的一个结点,现要求删去p所指结点,则正确的删除是( )(链中结点数大于2,p不是第一个结点)

A.p^.llink^.rlink:=p^.llink; p^.llink^.rlink:=p^.rlink; dispose(p); B.dispose(p); p^.llink^.rlink:=p^.llink; p^.llink^,rlink:=p^.rlink; C.p^.llink^.rlink:=p^.llink; dispose(p); p^.llink^.rlink:=p^.rlink; D.以上A,B,C都不对。 【南京理工大学 1997 一、1(2分)】

二、判断

1. 链表中的头结点仅起到标识的作用。( )【南京航空航天大学 1997 一、1(1分)】 2. 顺序存储结构的主要缺点是不利于插入或删除操作。( )【南京航空航天大学1997 一、2(1分)】

3.线性表采用链表存储时,结点和结点内部的存储空间可以是不连续的。( )

【北京邮电大学 1998 一、2(2分)】

4.顺序存储方式插入和删除时效率太低,因此它不如链式存储方式好。( )

【北京邮电大学 2002 一、2(1分)】

5. 对任何数据结构链式存储结构一定优于顺序存储结构。( )【南京航空航天大学 1997 一、3(1分)】

6.顺序存储方式只能用于存储线性结构。( )

【中科院软件所 1999 六、1-2(2分)】【上海海运学院 1997 一、1(1分)】

7.集合与线性表的区别在于是否按关键字排序。( )【大连海事大学 2001 一、5 ( 1分)】

8. 所谓静态链表就是一直不发生变化的链表。( )【合肥工业大学 2000 二、1(1分)】 9. 线性表的特点是每个元素都有一个前驱和一个后继。( )【合肥工业大学2001 二、1(1分)】

10. 取线性表的第i个元素的时间同i的大小有关. ( )【南京理工大学 1997 二、9(2

分)】

11. 循环链表不是线性表. ( )【南京理工大学 1998 二、1(2分)】

12. 线性表只能用顺序存储结构实现。( )【青岛大学 2001 四、2(1分)】 13. 线性表就是顺序存储的表。( )【青岛大学 2002 一、1(1分)】 14.为了很方便的插入和删除数据,可以使用双向链表存放数据。( )

【上海海运学院 1995 一、1(1分)】 【上海海运学院 1997 一、2(1分)】

15. 顺序存储方式的优点是存储密度大,且插入、删除运算效率高。( ) 【上海海运学院 1996 一、1(1分)】 【上海海运学院 1999 一、1(1分)】 16. 链表是采用链式存储结构的线性表,进行插入、删除操作时,在链表中比在顺序存储结构中效率高。 ( ) 【上海海运学院 1998 一、2(1分)】

三、填空

1.当线性表的元素总数基本稳定,且很少进行插入和删除操作,但要求以最快的速度存取线性表中的元素时,应采用_______存储结构。【北方交通大学 2001 二、4】

2.线性表L=(a1,a2,?,an)用数组表示,假定删除表中任一元素的概率相同,则删除一个元素平均需要移动元素的个数是________。【北方交通大学 2001 二、9】

3.设单链表的结点结构为(data,next),next为指针域,已知指针px指向单链表中data为x的结点,指针py指向data为y的新结点 , 若将结点y插入结点x之后,则需要执行以下语句:_______; ______;【华中理工大学 2000 一、4(2分)】

4.在一个长度为n的顺序表中第i个元素(1<=i<=n)之前插入一个元素时,需向后移动________个元素。

【北京工商大学 2001 二、4(4分)】

5.在单链表中设置头结点的作用是________。【哈尔滨工业大学 2000 二、1(1分)】 6.对于一个具有n个结点的单链表,在已知的结点*p后插入一个新结点的时间复杂度为________,在给定值为x的结点后插入一个新结点的时间复杂度为________。【哈尔滨工业大学 2001 一、1(2分)】

7.根据线性表的链式存储结构中每一个结点包含的指针个数,将线性链表分成________和_______;而又根据指针的连接方式,链表又可分成________和________。【西安电子科技大学1998 二、4(3分)】

8. 在双向循环链表中,向p所指的结点之后插入指针f所指的结点,其操作是_______、_______、_______、________。【中国矿业大学 2000 一、1(3分)】 9. 在双向链表结构中,若要求在p 指针所指的结点之前插入指针为s 所指的结点,则需执行下列语句:

s^ .next:=p; s^ .prior:= ________;p^ .prior:=s;________:=s; 【福州大学 1998 二、7 (2分)】

10.链接存储的特点是利用________来表示数据元素之间的逻辑关系。【中山大学 1998 一、1 (1分)】

11.顺序存储结构是通过________表示元素之间的关系的;链式存储结构是通过________表示元素之间的关系的。【北京理工大学 2001 七、2 (2分)】

12. 对于双向链表,在两个结点之间插入一个新结点需修改的指针共 ______个,单链表为_______个。

【南京理工大学 2000 二、2 (3分)】

13. 循环单链表的最大优点是:________。【福州大学 1998 二、3 (2分)】

14. 已知指针p指向单链表L中的某结点,则删除其后继结点的语句是:________

入到线性表的适当位置上,以保持线性表的有序性,并在设计前说明设计思想,最后说明所设计算法的时间复杂度。

【西安电子科技大学 1999计应用 1997 二 (10分)】

类似本题的另外叙述有:

(1) 试编制在线性表L={12,13,21,24,28,30,42,}中插入数据元素26的程序。(要求该程序用turbo Pascal语言编制并能在计算机上运行,结点类型为链式结构)【大连海事大学 1996 二、1 (16分)】

16. 假设一个单循环链表,其结点含有三个域pre、data、link。其中data为数据域;pre为指针域,它的值为空指针(NIL);link为指针域,它指向后继结点。请设计算法,将此表改成双向循环链表。

【西安电子科技大学 1999软件 五(10分)】

17. 已知递增有序的单链表A,B分别存储了一个集合,请设计算法以求出两个集合A和B 的差集A-B(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。

【西安电子科技大学2000计应用1997 二 (10分)】

18. 已知一个单链表中每个结点存放一个整数,并且结点数不少于2,请设计算法以判断该链表中第二项起的每个元素值是否等于其序号的平方减去其前驱的值,若满足则返回ture,否则返回false.

【西安电子科技大学2000软件1997 二(10分)】

19.两个整数序列A=a1,a2,a3,?,am和B=b1,b2,b3,?,bn已经存入两个单链表中,设计一个算法,判断序列B是否是序列A的子序列。【东北大学 1999 二 (10分)】

20.L1与L2分别为两单链表头结点地址指针,且两表中数据结点的数据域均为一个字母。设计把L1中与L2中数据相同的连续结点顺序完全倒置的算法。【东北大学 1997 四 (15分)】

L1acabdad?例:

L2abd?

类似本题的另外叙述有:

(1) 知L为链表的头结点地址,表中共有m(m>3)个结点,从表中第i个结点(1

L ama1a1

【东北大学 1998 三 (15分)】

21. 请写一个算法将顺序存储结构的线性表(a1...an)逆置为(an...a1)。【大连海事大学1996八(6分)】

类似本题的另外叙述有:

(1) 设有一带头结点的单链表,编程将链表颠倒过来.要求不用另外的数组或结点完成.

【南京航空航天大学 1999 八 (10分)】

(2) 设有一个带头结点的单向链表,数据项递减有序。写一算法,重新排列链表,使数据项递增有序,要求算法时间复杂度为O(n)。(注:用程序实现)【南京航空航天大学 1997 七 (12分)】

(3) 试编写求倒排循环链表元素的算法。【南京航空航天大学 1995 十二 (10分)】

(4) 请设计算法将不带头结点的单链表就地逆置。【北方交通大学 2001 三 (12分)】 (5) 试编写算法 ,将不设表头结点的、不循环的单向链表就地逆转。【北方交通大学1997五(10分)】

(6) 有一个单链表L(至少有1个结点),其头结点指针为head,编写一个过程将L逆置,即最后一个结点变成第一个结点,原来倒数第二个结点变成第二个结点,如此等等。【燕山大学 2001 四、2(8分)】

22.设有一个由正整数组成的无序(向后)单链表,编写完成下列功能的算法:

(1)找出最小值结点,且打印该数值;

(2)若该数值是奇数,则将其与直接后继结点的数值交换; (3)若该数值是偶数,则将其直接后继结点删除。【东北大学 2000 二 (15分)】

23.已知L为没有头结点的的单链表中第一个结点的指针,每个结点数据域存放一个字符,该字符可能是英文字母字符或数字字符或其它字符,编写算法构造三个以带头结点的单循环链表表示的线性表,使每个表中只含同一类字符。(要求用最少的时间和最少的空间)【东北大学 2002 三(15分)】

24.在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素。例如:(7,10,10,21,30,42,42,42,51,70)将变作(7,10,21,30,42,51,70),分析算法的时间复杂度。【北京工业大学 1996 三 (15分)】

25.在输入数据无序的情况下,建立一个数据值为整型的递增有序的顺序存储线性表L,且要求当输入相同数据值时,线性表中不能存在数据值相同的数据元素,试写出其算法。 顺序存储结构的线性表描述为:

CONST maxlen={线性表可能达到的最大长度}; TYPE sqlisttp=RECORD

elem:array[1..maxlen] of integer; last :0..maxlen

END;

VAR L: sqlisttp;【同济大学 1998 二 (12分 )】

26.设有一个正整数序列组成的有序单链表(按递增次序有序,且允许有相等的整数存在),试编写能实现下列功能的算法 :(要求用最少的时间和最小的空间)

(1)确定在序列中比正整数x大的数有几个(相同的数只计算一次,如序列{20,20,17,16,15,15,11,10,8,7,7,5,4}中比10大的数有5个);

(2) 在单链表将比正整数x小的数按递减次序排列; (3) 将正整数(比)x大的偶数从单链表中删除。【东北大学 2001 二 (17分)】

27. 编写一个算法来交换单链表中指针P所指结点与其后继结点,HEAD是该链表的头指针,P指向该链表中某一结点。【吉林大学 2001 二、1 (7分)】 类似本题的另外叙述有:

(1) 已知非空线性链表第一个结点由List指出,请写一算法,交换p所指的结点与其下一个结点在链表中的位置(设p指向的不是链表最后那个结点)。【北京航空航天大学 1999 五 (10分)】

(2) 已知任意单链表如图所示(编者略去图)。Head为表头指针,指向表的第一个元素,p为指向表中任意结点的指针,试设计一个算法,将p指向的结点和其后面结点交换位置(可采用任何高级语言描述算法)。

【山东大学 1992 二 ( 12分)】

28.设键盘输入n个英语单词,输入格式为n, w1, w2, ?,wn,其中n表示随后输入英语单词

个数,试编一程序,建立一个单向链表,实现:(10分)

(1)如果单词重复出现,则只在链表上保留一个。(单考生做)。

(2)除满足(1)的要求外。链表结点还应有一个计数域,记录该单词重复出现的次数,然后输出出现次数最多的前k(k<=n)个单词(统考生做)。【南京航空航天大学 1998 九 (10分)】

29.已知一双向循还链表,从第二个结点至表尾递增有序,(设a130. 已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为0(n)、空间复杂度为0(1)的算法,该算法删除线性表中所有值为item的数据元素。(O(1)表示算法的辅助空间为常量)。

【北京航空航天大学 2000 五(10分)】

31.设民航公司有一个自动预订飞机票的系统,该系统中有一张用双重链表示的乘客表,表中结点按乘客姓氏的字母序相链。例如,下面是张某个时刻的乘客表。试为该系统写出一个当任一乘客要订票时修改乘客表的算法。

序号 data Llink Rlink 1 Liu 6 5 2 Chan 4 9 3 Wang 5 7 4 Bao 0 2 5 Mai 1 3 6 Dong 8 1 7 Xi 3 0 8 Deng 9 6

9 Cuang 2 8

【北方交通大学 2000 六(17分)】

32.设有一头指针为L的带有表头结点的非循环双向链表,其每个结点中除有pred(前驱指针),data(数据)和next(后继指针)域外,还有一个访问频度域freq。在链表被起用前,其值均初始化为零。每当在链表中进行一次Locate(L,x)运算时,令元素值为x的结点中freq域的值增1,并使此链表中结点保持按访问频度非增(递减)的顺序排列,同时最近访问的结点排在频度相同的结点的最后,以便使频繁访问的结点总是靠近表头。试编写符合上述要求的Locate(L,x)运算的算法,该运算为函数过程,返回找到结点的地址,类型为指针型。【清华大学 1997 二 (10分)】

33.给定(已生成)一个带表头结点的单链表,设head为头指针,结点的结构为(data,next),data为整型元素,next为指针,试写出算法:按递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间。(要求;不允许使用数组作辅助空间)【华中理工大学 2000 八、2 (13分)】

34.已知三个带头结点的线性链表A、B和C中的结点均依元素值自小至大非递减排列(可能存在两个以上值相同的结点),编写算法对A表进行如下操作:使操作后的链表A中仅留下三个表中均包含的数据元素的结点,且没有值相同的结点,并释放所有无用结点。限定算法的时间复杂度为O(m+n+p),其中m、n和p分别为三个表的长度。【清华大学 1995 一 (15分)】

第2章 线性表

一.选择题 1.A 11.4B 2.B 11.5C 3.C 4.A 5.D 6.D 7.D 12.B 13.C 25.B 14.C 26.A 15.C 27.D 5.× 8.C 9.B 10.B,C 16.A 17.A 18.A 11.1I 11.2I 11.3E 19.D 20.C 21.B 22.D 23.C 24.B 二.判断题 1. × 2.√ 13. × 14. √ 3. √ 15.× 4.× 16. √ 6. × 7. × 8.× 9.× 10.× 11.× 12.× 部分答案解释如下。 1、 头结点并不“仅起”标识作用,并且使操作统一。另外,头结点数据域可写入链表长度,

或作监视哨。

4.两种存储结构各有优缺点,应根据实际情况选用,不能笼统说哪一个好。 7.集合中元素无逻辑关系。

9.非空线性表第一个元素无前驱,最后一个元素无后继。 13.线性表是逻辑结构,可以顺序存储,也可链式存储。

三.填空题

1.顺序 2.(n-1)/2 3.py->next=px->next; px->next=py 4 .n-i+1

5.主要是使插入和删除等操作统一,在第一个元素之前插入元素和删除第一个结点不必另作判断。另外,不论链表是否为空,链表指针不变。 6.O(1),O(n) 7.单链表,多重链表,(动态)链表,静态链表 8.f->next=p->next; f->prior=p; p->next->prior=f; p->next=f; 9.p^.prior s^.prior^.next

10. 指针 11.物理上相邻 指针 12.4 2 13.从任一结点出发都可访问到链表中每一个元素。

14.u=p->next; p->next=u->next; free(u); 15.L->next->next==L 16.p->next!=null

17.L->next==L && L->prior==L 18.s->next=p->next;p->next=s; 19.(1) IF pa=NIL THEN return(true);

(2) pb<>NIL AND pa^.data>=pb^.data (3) return(inclusion(pa,pb)); (4) pb:=pb^.next; (5) return(false); 非递归算法:

(1)pre:=pb; (2) pa<>NIL AND pb<>NIL AND pb^.data>=pa^.data (3)pa:=pa^.next; pb:=pb->next;

(4)pb:=pre^.next;pre:=pb;pa:=pa^.next;(5)IF pa=NIL THEN return(true) ELSE

return(false);

[注]:本题是在链表上求模式匹配问题。非递归算法中用指针pre指向主串中开始结点(初始时为第一元素结点)。若主串与子串对应数据相等,两串工作指针pa和pb后移;否则,主串工作指针从pre的下一结点开始(这时pre又指向新的开始结点),子串工作指针从子串第一元素开始,比较一直继续到循环条件失败。若pa为空,则匹配成功,返回true,否则,返回false。

20.A.VAR head:ptr B. new(p) C. p^.data:=k D. q^.next:=p E. q:=p(带头结点) 21.(1)new(h);∥生成头结点,以便于操作。

(2)r^.next:=p; (3) r^.next:=q; (4) IF (q=NIL) THEN r^.next:=p; 22.A: r^.link^.data<>max AND q^.link^.data<>max

B: r:=r^.link C: q^.link D: q^.link E: r^.link F: r^.link G: r:=s(或r:= r^.link) H: r:=r^.link I: q^.link:=s^.link 23.(1)la (2)0 (3)j

(2)j:=1;

(3)p:=p^.right ∥工作指针后移 (4)s^.left:=p

(5)p^.right^.left:=s; ∥p后继的前驱是s (6)s^.left:=p;

25.(1)i<=L.last ∥L.last 为元素个数 (2)j:=j+1 ∥有值不相等的元素

(3)L.elem[j]:=L.elem[i] ∥元素前移 (4)L.last:=j ∥元素个数

26.(A)p^.link:=q;∥拉上链,前驱指向后继 (B)p:=q;∥新的前驱

(C)p^.link:=head;∥形成循环链表 (D)j:=0; ∥计数器,记被删结点 (E)q:=p^.link∥记下被删结点 (F)p^.link=q^.link ∥删除结点

27. (1)p:=r;∥r指向工作指针s的前驱,p指向最小值的前驱。 (2)q:=s;∥q指向最小值结点,s是工作指针

(3)s:=s^.link∥工作指针后移

(4)head:=head^.next;∥第一个结点值最小;

(5)p^link:=q^.link;∥跨过被删结点(即删除一结点) 28.(1) l^.key:=x;∥头结点l这时起监视哨作用 (2) l^.freq:=p^.freq ∥头结点起监视哨作用

(3) q->pre->next=q->next; q->next->pre=q->pre; ∥先将q结点从链表上摘下

q^.next:=p; q^.pre:=p^.pre; p^.pre->next:=q; p^.pre:=q; ∥结点q插入

结点p前

(4) q^.freq=0 ∥链表中无值为x的结点,将新建结点插入到链表最后(头结点

前)。

29.(1)a^.key:=’@’∥a的头结点用作监视哨,取不同于a链表中其它数据域的值 (2)b^.key:=p^.key∥b的头结点起监视哨作用

(3)p:=p^.next∥找到a,b表中共同字母,a表指针后移 (4)0(m*n)

30. C 部分:(1)p!=null ∥链表未到尾就一直作

(2)q ∥将当前结点作为头结点后的第一元素结点插入

31. (1)L=L->next; ∥暂存后继 (2)q=L; ∥待逆置结点 (3)L=p; ∥头指针仍为L

32. (1) p^.next<>p0 (2)r:= p^.next (3) p^.next:= q0; (4) q0:= p; (5) p:=r

33. (1)r (2)NIL (3)x=x; (7)r (8)p (9)r (10)NIL (11)NIL 34.(1)pa!=ha ∥或pa->exp!=-1

(2)pa->exp==0 ∥若指数为0,即本项为常数项 (3)q->next=pa->next ∥删常数项 (4)q->next ∥取下一元素 (5)=pa->coef*pa->exp

(6)-- ∥指数项减1

(7)pa ∥前驱后移,或q->next (8)pa->next ∥取下一元素 35.(1)q:=p; ∥q是工作指针p的前驱

(2)p^.data>m ∥p是工作指针

(3)r:=q; ∥r 记最大值的前驱, (4)q:=p; ∥或q:=q^.next;

(5)r^.next:=q^.next; ∥或r^.next:=r^.next^.next 删最大值结点 36.(1)L->next=null ∥置空链表,然后将原链表结点逐个插入到有序表中 (2)p!=null ∥当链表尚未到尾,p为工作指针

(3)q!=null ∥查p结点在链表中的插入位置,这时q是工作指针。 (4)p->next=r->next ∥将p结点链入链表中

(5)r->next=p ∥r是q的前驱,u是下个待插入结点的指针。 37.程序(a) PASCAL部分(编者略)

程序(b) C部分

(1)(A!=null && B!=null) ∥两均未空时循环

(2)A->element==B->element ∥两表中相等元素不作结果元素 (3)B=B->link ∥向后移动B表指针

(4)A!=null ∥将A 表剩余部分放入结果表中 (5)last->link=null ∥置链表尾

四、 应用题 1.(1)选链式存储结构。它可动态申请内存空间,不受表长度(即表中元素个数)的

影响,插入、删

除时间复杂度为O(1)。

(2)选顺序存储结构。顺序表可以随机存取,时间复杂度为O(1)。

2.链式存储结构一般说克服了顺序存储结构的三个弱点。首先,插入、删除不需移动

元素,只修改指针,时间复杂度为O(1);其次,不需要预先分配空间,可根据需要动态申请空间;其三,表容量只受可用内存空间的限制。其缺点是因为指针增加了空间开销,当空间不允许时,就不能克服顺序存储的缺点。

3.采用链式存储结构,它根据实际需要申请内存空间,而当不需要时又可将不用结点空间返还给系统。在链式存储结构中插入和删除操作不需要移动元素。

4.线性表 栈 队列 串 顺序存储结构和链式存储结构。 顺序存储结构的定义是:

CONST maxlen=线性表可能达到的最大长度; TYPE sqlisttp=RECORD

elem:ARRAY[1..maxlen] OF ElemType; last:0..maxlen; END; 链式存储结构的定义是: TYPE pointer=↑nodetype; nodetype=RECORD

data:ElemType; next:pointer; END;

linklisttp=pointer; 5.顺序映射时,ai与ai+1的物理位置相邻;链表表示时ai与ai+1的物理位置不要求相邻。 6.在线性表的链式存储结构中,头指针指链表的指针,若链表有头结点则是链表的头结点的指针,头指针具有标识作用,故常用头指针冠以链表的名字。头结点是为了操作的统一、方便而设立的,放在第一元素结点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等),有头结点后,对在第一元素结点前插入结点和删除第一结点,其操作与对其它结点的操作统一了。而且无论链表是否为空,头指针均不为空。首元结点也就是第一元素结点,它是头结点后边的第一个结点。

7.见上题6。

8.(1)将next域变为两个域: pre和next,其值域均为0..maxsize。初始化时,头结点(下标为0的元素)其next域值为1,其pre域值为n(设n是元素个数,且n

9. 在单链表中不能从当前结点(若当前结点不是第一结点)出发访问到任何一个结点,链表只能从头指针开始,访问到链表中每个结点。在双链表中求前驱和后继都容易,从当前结点向前到第一结点,向后到最后结点,可以访问到任何一个结点。

10.本题是链表的逆置问题。设该链表带头结点,将头结点摘下,并将其指针域置空。然后从第一元素结点开始,直到最后一个结点为止,依次前插入头结点的后面,则实现了链表的逆置。 11.该算法的功能是判断链表L是否是非递减有序,若是则返回“true”;否则返回“false“。pre指向当前结点,p指向pre的后继。

12.q=p->next; p->next=q->next; free(q);

13. 设单链表的头结点的头指针为head,且pre=head; while(pre->next!=p) pre=pre->next; s->next=p; pre->next=s;

14.设单链表带头结点,工作指针p初始化为p=H->next;

(1) while(p!=null && p->data!=X) p=p->next;

if(p= =null) return(null);∥查找失败 else return(p);∥查找成功

(2) while(p!=null && p->datanext;

if(p==null || p->data>X) return(null);∥查找失败 else return(p);

(3) while(p!=null && p->data>X) p=p->next;

if(p==null || p->data

15.本程序段功能是将pa和pb链表中的值相同的结点保留在pa链表中(pa中与pb中不同结点删除),pa是结果链表的头指针。链表中结点值与从前逆序。S1记结果链表中结点个数(即pa与pb中相等的元素个数)。S2记原pa链表中删除的结点个数。 16.设 q:=p^.llink; 则

q^.rlink:=p^.rlink; p^.rlink^.llink:=q; p^.llink:=q^.llink;

q^.llink^.rlink:=p; p^.rlink:=q; q^.llink:=p 17.(1)前两个语句改为:

p.llink^.rlink<- p^.rlink; p^.rlink^.llink<- p^.llink;

(2)后三个语句序列应改为:

q^.rlink<- p^.rlink;∥以下三句的顺序不能变

p^.rlink^.llink<- q; p^.rlink<- q;

18.mp是一个过程,其内嵌套有过程subp。

subp(s,q)的作用是构造从s到q的循环链表。

subp(pa,pb)调用结果是将pa到pb的前驱构造为循环链表。

subp(pb,pa)调用结果是将pb到pa的前驱(指在L链表中,并非刚构造的pa循环

链表中)构造为循环链表。

总之,两次调用将L循环链表分解为两个。第一个循环链表包含从pa到pb的前驱,L中除刚构造的pa到pb前驱外的结点形成第二个循环链表。 19.在指针p所指结点前插入结点s的语句如下:

s->pre=p->pre; s->next=p; p->pre->next=s; p->pre=s;

20.(A) f1<>NIL并且f2<>NIL

(B) f1↑.data < f2↑.data (C) f2↑.data

(E) f1<- f1↑.link 或f2=f2↑.link;

21. 1)本算法功能是将双向循环链表结点的数据域按值自小到大排序,成为非递减(可能包括数据域值相等的结点)有序双向循环链表。

2)(1)r->prior=q->prior;∥将q结点摘下,以便插入到适当位置。

(2)p->next->prior=q;∥(2)(3)将q结点插入 (3)p->next=q;

(4)r=r->next;或r=q->next;∥后移指针,再将新结点插入到适当位置。

五、 算法设计题

1.[题目分析]因为两链表已按元素值递增次序排列,将其合并时,均从第一个结点起进行比较,将小的链入链表中,同时后移链表工作指针。该问题要求结果链表按元素值递减次序排列。故在合并的同时,将链表结点逆置。 LinkedList Union(LinkedList la,lb)

∥la,lb分别是带头结点的两个单链表的头指针,链表中的元素值按递增序排列,本算法

将两链表合并成一个按元素值递减次序排列的单链表。

{ pa=la->next; pb=lb->next;∥pa,pb分别是链表la和lb的工作指针

la->next=null; ∥la作结果链表的头指针,先将结果链表初始化为空。

while(pa!=null && pb!=null) ∥当两链表均不为空时作 if(pa->data<=pb->data)

{ r=pa->next; ∥将pa 的后继结点暂存于r。

pa->next=la->next; ∥将pa结点链于结果表中,同时逆置。

la->next=pa;

pa=r; ∥恢复pa为当前待比较结点。 }

else

{r=pb->next;∥ 将pb 的后继结点暂存于r。

pb->next=la->next; ∥将pb结点链于结果表中,同时逆置。 la->next=pb;

pb=r; ∥恢复pb为当前待比较结点。 }

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语句,不可能执行两个,只能二者取一,即哪个表尚未到尾,就将其逆置到结果表中,即将剩余结点依次前插入到结果表的头结点后面。 与本题类似的其它题解答如下: (1)[问题分析]与上题类似,不同之处在于:一是链表无头结点,为处理方便,给加上头结点,处理结束再删除之;二是数据相同的结点,不合并到结果链表中;三是hb链表不能被破坏,即将hb的结点合并到结果链表时,要生成新结点。 LinkedList Union(LinkedList ha, hb)

∥ha和hb是两个无头结点的数据域值递增有序的单链表,本算法将hb中并不出现在ha

中的数据合并到ha中,合并中不能破坏hb链表。 {LinkedList la;

la=(LinkedList)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->data>pb->data)∥处理hb中数据。

{r=(LinkedList)malloc(sizeof(LNode));∥申请空间 r->data=pb->data; pre->next=r;

pre=r;∥将新结点链入结果链表。

pb=pb->next;∥hb链表中工作指针后移。 }

else∥处理pa->data=pb->data; {pre->next=pa; pre=pa;

pa=pa->next;∥两结点数据相等时,只将ha的数据链入。 pb=pb->next;∥不要hb的相等数据 }

if(pa!=null)pre->next=pa;∥将两链表中剩余部分链入结果链表。 else pre->next=pb;

free(la);∥释放头结点.ha,hb指针未被破坏。 }∥算法nion结束。

(2)本题与上面两题类似,要求结果指针为lc,其核心语句段如下: pa=la->next;pb=hb->next;

lc=(LinkedList )malloc(sizeof(LNode)); pc=lc;∥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);∥释放原来两链表的头结点。 算法时间复杂度为O(m+n),其中m和n分别为链表la和lb的长度。

2.[题目分析]本组题有6个,本质上都是链表的合并操作,合并中有各种条件。与前组题不同的是,叙述上是用线性表代表集合,而操作则是求集合的并、交、差(A∪B,A∩B,A-B)等。

本题与上面1.(2)基本相同,不同之处1.(2)中链表是“非递减有序”,(可能包含相等元素),本题是元素“递增有序”(不准有相同元素)。因此两表中合并时,如有元素值相等元素,则应删掉一个。

LinkedList Union(LinkedList ha,hb)

∥线性表A和B代表两个集合,以链式存储结构存储,元素递增有序。ha和hb分别

是其链表的头指针。本算法求A和B的并集A∪B,仍用线性表表示,结果链表元素也是递增有序。

{ pa=ha->next;pb=hb->next;∥设工作指针pa和pb。 pc=ha;∥pc为结果链表当前结点的前驱指针。 while(pa&&pb)

if(pa->datadata)

{pc->next=pa;pc=pa;pa=pa->next;}

入。

while(p!=null)

{r=p->next;∥暂存p的后继。 q=la;

while(q->next!=null&&q->next->datadata)q=q->next;∥查找插入位置。 p->next=q->next;∥将p结点链入链表。 q->next=p; p=r; }

与本题有类似叙述的题的解答:

(1)本题也是链表排序问题,虽没象上题那样明确要求“利用直接插入的原则”来排序,仍可用上述算法求解,这里不再赘述。

7.[题目分析]本题要求将一个链表分解成两个链表,两个链表都要有序,两链表建立过程中不得使用NEW过程申请空间,这就是要利用原链表空间,随着原链表的分解,新建链表随之排序。

PROC discreat(VAR listhead,P,Q:linkedlist)

∥listhead是单链表的头指针,链表中每个结点由一个整数域DATA和指针域NEXT组成。本算法将链表listhead分解成奇数链表和偶数链表,分解由P和Q指向,且P和Q链表是有序的。

P:=NIL;Q:=NIL;∥P和Q链表初始化为空表。 s:=listhead; WHILE(s<>NIL)DO

[r:=s^.NEXT; ∥暂存s的后继。 IF s^.DATA DIV 2=0 ∥处理偶数。

THEN IF P=NIL THEN[P:=s;P^.NEXT:=NIL;] ∥第一个偶数链结点。

ELSE[pre:=P;

IF pre^.DATA>s^.DATA THEN[s^.NEXT:=pre;P:=s;∥插入当前最小值结

点修改头指针]

ELSE[WHILE pre^.NEXT<>NIL DO

IF pre^.NEXT^.DATA

s^.NEXT:=pre^.NEXT; ∥链入此结点。 pre^.NEXT:=s; ]

]

ELSE∥处理奇数链。

IF Q=NIL THEN[Q:=s;Q^.NEXT:=NIL;] ∥第一奇数链结点。 ELSE[pre:=Q;

IF pre^.DATA>s^.DATA THEN[s^.NEXT:=pre; Q:=s; ]∥修改头指针。

ELSE[WHILE pre^.NEXT<>NIL DO ∥查找插入位置。

IF pre^.NEXT^.DATA

]∥结束奇数链结点

s:=r;∥s指向新的待排序结点。 ]∥结束“WHILE(s<>NIL)DO” ENDP;∥结束整个算法。 [算法讨论]由于算法要求“不得使用NEW过程申请空间,也没明确指出链表具有头结点,所以上述算法复杂些,它可能需要在第一个结点前插入新结点,即链表的头指针会发生变化。如有头结点,算法不必单独处理在第一个结点前插入结点情况,算法会规范统一,下面的(1)是处理带头结点的例子。算法中偶数链上结点是靠数据整除2等于0(DATA DIV 2=0)判断的。

类似本题的其它题解答如下:

(1)[题目分析]本题基本类似于上面第7题,不同之处有二。一是带头结点,二是分解后的两个链表,一个是数据值小于0,另一个是数据值大于0。由于没明确要求用类PASCAL书写算法,故用C书写如下。

void DisCreat1(LinkedList A)

∥A是带头结点的单链表,链表中结点的数据类型为整型。本算法将A分解成两个单链表B和C,B中结点的数据小于零,C中结点的数据大于零。 {B=A;

C=(LinkedList )malloc(sizeof(LNode));∥为C申请结点空间。 C->next=null ∥C初始化为空表。 p=A->next; ∥p为工作指针。 B->next=null; ∥B表初始化。 while(p!=null)

{r=p->next; ∥暂存p的后继。

if (p->data<0)∥小于0的放入B表。

{p->next=B->next; B->next=p; }∥将小于0的结点链入B表。 else {p->next=C->next; C->next=p; } p=r;∥p指向新的待处理结点。 }

}∥算法结束。

[算法讨论]因为本题并未要求链表中结点的数据值有序,所以算法中采取最简单方式:将新结点前插到头结点后面(即第一元素之前)。 (2) 本题同上面第7题,除个别叙述不同外,本质上完全相同,故不再另作解答。

(3)[题目分析]本题中的链表有头结点,分解成表A和表B,均带头结点。分解后的A表含有原表中序号为奇数的元素,B表含有原A表中序号为偶数的元素。由于要求分解后两表中元素结点的相对顺序不变,故采用在链表尾插入比较方便,这使用一指向表尾的指针即可方便实现。

void DisCreat3(LinkedList A)

∥A是带头结点的单链表,本算法将其分解成两个带头结点的单链表,A表中含原表中序号为奇数

∥的结点,B表中含原表中序号为偶数的结点。链表中结点的相对顺序同原链表。 {i=0;∥i记链表中结点的序号。

B=(LinkedList)malloc(sizeof(LNode);∥创建B表表头。 B->next=null; ∥B表的初始化。

LinkedList ra,rb;∥ra和rb将分别指向将创建的A表和B表的尾结点。

ra=A;rb=B;

p=A->next; ∥p为链表工作指针,指向待分解的结点。 A->next=null; ∥置空新的A表 while(p!=null)

{r=p->next; ∥暂存p的后继。 i++;

if(i%2==0) ∥处理原序号为偶数的链表结点。

{p->next=rb->next;∥在B表尾插入新结点; rb->next=p; rb=p;∥rb指向新的尾结点; }

else∥处理原序号为奇数的结点。

{p->next=ra->next; ra->next=p; ra=p; }

p=r; ∥将p恢复为指向新的待处理结点。 }∥算法结束

8.[题目分析]题目要求重排n个元素且以顺序存储结构存储的线性表,使得所有值为负数的元素移到正数元素的前面。这可采用快速排序的思想来实现,只是提出暂存的第一个元素(枢轴)并不作为以后的比较标准,比较的标准是元素是否为负数。 int Rearrange(SeqList a; int n)

∥a是具有n个元素的线性表,以顺序存储结构存储,线性表的元素是整数。本算法重

排线性表a,

∥使所有值为负数的元素移到所有值为正数的数的前面。 {i=0; j=n-1; ∥ i,j为工作指针(下标),初始指向线性表a的第1个和第n个元

素。

t=a[0]; ∥暂存枢轴元素。 while(i

{while(i=0) j--; ∥ 若当前元素为大于等于零,则指针前移。 if(i

while(i

a[i]=t; ∥将原第一元素放到最终位置。 }

[算法讨论] 本算法时间复杂度为O(n)。算法只是按题目要求把正负数分开,如要求统计负数和大于等于零的个数,则最后以t来定。如t为负数,则0至i共i+1个负数,n-1-i个正数(包括零)。另外,题目并未提及零的问题,笔者将零放到正数一边。对此问题的扩充是若元素包含正数、负数和零,并要求按负数、零、正数的顺序重排线性表,统计负数、零、正数的个数。请读者利用上面解题思想自行解答。 类似本题的选了5 个题,其解答如下:

(1)与上面第8题不同的是,这里要求以an为参考元素,将线性表分成左右两部分。左半部分的元素都小于等于an,右半部分的元素都大于an,an位于分界位置上。其算法主要片段语句如下:

i=1;j=n;

t=a[n]; ∥暂存参考元素。 while(i

{while(i

while(it) j--; ∥当前元素大于参考元素时指针前移。 if(i

a[i]=t; ∥参考元素置于分界位置。

(2) [题目分析]本题要求将线性表A分成B和C两个表,表B和表C不另占空间,而是利用表A的空间,其算法与第8题相同。这里仅把表B和表C另设空间的算法解答如下: void Rearrange2(int A[],B[],C[])

∥线性表A有n个整型元素,顺序存储。本算法将A拆成B和C 两个表,B中存放

大于

∥等于零的元素,C中存放小于零的元素。

{i=0; ∥i,j,k是工作指针,分别指向A、B和C表的当前元素。 j=k=-1; ∥j,k初始化为-1。 while(i

{if(A[i]<0) C[++k]=A[i++]; ∥将小于零的元素放入C表。 else B[++j]=A[i++]; ∥将大于零的元素放入B表。

[算法讨论]本题用一维数组存储线性表,结果线性表B和C中分别有j+1和k+1个元素。若采用教材中的线性表,则元素的表示作相应改变,例如A.elem[i],而最后B和C表应置上表的长度,如B.length=j和C.length=k。

(3) 本题与第8题本质上相同,第8题要求分开正数和负数,这里要求分开奇数和偶数,判别方式是a[i]%2==0,满足时为偶数,反之为奇数。 (4) 本题与第8题相同,只是叙述不同。

(5) 本题与第8题基本相同,不同之处在于这里的分界元素是整数19(链表中并不要

求一定有19)。本题要求用标准pascal描述算法,如下所示。 TYPE arr=ARRAY[1..1000] OF integer; VAR a:arr;

PROCEDURE Rearrange5(VAR a:arr);

∥a是n(设n=1000)个整数组成的线性表,用一维数组存储。本算法将n个元素

中所有大于等于19的整数放在所有小于19的整数之后。

VAR i,j,t:integer; BEGIN

i:=1;j:=n;t:=a[1] ;∥i,j指示顺序表的首尾元素的下标,t暂存分界元素 WHILE(i

WHILE (i=19) DO j:=j-1;

IF(i

IF(i

[算法讨论] 分界元素t放入a[i],而不论它的值如何。算法中只用了一个t中间变量,符合空间复杂度O(1)的要求。算法也满足时间复杂度O(n)的要求。

9.[题目分析] 本题要求在单链表中删除最小值结点。单链表中删除结点,为使结点删除后不出现“断链”,应知道被删结点的前驱。而“最小值结点”是在遍历整个链表后才能知道。所以算法应首先遍历链表,求得最小值结点及其前驱。遍历结束后再执行删除操作。

LinkedList Delete(LinkedList L)

∥L是带头结点的单链表,本算法删除其最小值结点。

{p=L->next; ∥p为工作指针。指向待处理的结点。假定链表非空。 pre=L; ∥pre指向最小值结点的前驱。

q=p; ∥q指向最小值结点,初始假定第一元素结点是最小值结点。 while(p->next!=null)

{if(p->next->datadata){pre=p;q=p->next;} ∥查最小值结点 p=p->next; ∥指针后移。 }

pre->next=q->next;∥从链表上删除最小值结点 free(q); ∥释放最小值结点空间 }∥结束算法delete。

[算法讨论] 算法中函数头是按本教材类C描述语言书写的。原题中void delete(linklist &L),是按C++的“引用”来写的,目的是实现变量的“传址”,克服了C语言函数传递只是“值传递”的缺点。

10.[题目分析] 本题要求将链表中数据域值最小的结点移到链表的最前面。首先要查找最小值结点。将其移到链表最前面,实质上是将该结点从链表上摘下(不是删除并回收空间),再插入到链表的最前面。

LinkedList delinsert(LinkedList list)

∥list是非空线性链表,链结点结构是(data,link),data是数据域,link是链域。

∥本算法将链表中数据域值最小的那个结点移到链表的最前面。 {p=list->link;∥p是链表的工作指针

pre=list; ∥pre指向链表中数据域最小值结点的前驱。 q=p; ∥q指向数据域最小值结点,初始假定是第一结点 while (p->link!=null)

{if(p->link->datadata){pre=p;q=p->link;} ∥找到新的最小值结点; p=p->link; }

if (q!=list->link) ∥若最小值是第一元素结点,则不需再操作 {pre->link=q->link; ∥将最小值结点从链表上摘下; q->link= list->link;∥将q结点插到链表最前面。 list->link=q;

}

}∥算法结束

[算法讨论] 算法中假定list带有头结点,否则,插入操作变为q->link=list;list=q。 11.[题目分析] 知道双向循环链表中的一个结点,与前驱交换涉及到四个结点(p结点,前驱结点,前驱的前驱结点,后继结点)六条链。

void Exchange(LinkedList p)

∥p是双向循环链表中的一个结点,本算法将p所指结点与其前驱结点交换。 {q=p->llink;

本文来源:https://www.bwwdw.com/article/46r7.html

Top