第2章线性表
四 应用题
1.线性表有两种存储结构:一是顺序表,二是链表。试问:
(1)如果有 n个线性表同时并存,并且在处理过程中各表的长度会动态变化,线性表的总数也会自动地改变。在此情况下,应选用哪种存储结构? 为什么?
选链式存储结构。它可动态申请内存空间,不受表长度(即表中元素个数)的影响,插入、删除时间复杂度为O(1)。
(2)若线性表的总数基本稳定,且很少进行插入和删除,但要求以最快的速度存取线性表中的元素,那么应采用哪种存储结构?为什么?
选顺序存储结构。顺序表可以随机存取,时间复杂度为O(1)。
2.线性表的顺序存储结构具有三个弱点:其一,在作插入或删除操作时,需移动大量元素;其二,由于难以估计,必须预先分配较大的空间,往往使存储空间不能得到充分利用;其三,表的容量难以扩充。线性表的链式存储结构是否一定都能够克服上述三个弱点,试讨论之。
链式存储结构一般说克服了顺序存储结构的三个弱点。首先,插入、删除不需移动元素,只修改指针,时间复杂度为O(1);其次,不需要预先分配空间,可根据需要动态申请空间;其三,表容量只受可用内存空间的限制。其缺点是因为指针增加了空间开销,当空间不允许时,就不能克服顺序存储的缺点。
3.若较频繁地对一个线性表进行插入和删除操作,该线性表宜采用何种存储结构?为什么?
采用链式存储结构,它根据实际需要申请内存空间,而当不需要时又可将不用结点空间返还给系统。在链式存储结构中插入和删除操作不需要移动元素。
4.线性结构包括
线性表 栈 队列 串
线性表的存储结构分成
顺序存储结构和链式存储结构。
5.线性表(a1,a2,…,an)用顺序映射表示时,ai和ai+1(1<=i<n〉的物理位置相邻吗?链接表示时呢?
顺序映射时,ai与ai+1的物理位置相邻;链表表示时ai与ai+1的物理位置不要求相邻。
6. 说明在线性表的链式存储结构中,头指针与头结点之间的根本区别;头结点与首元结点的关系。
在线性表的链式存储结构中,头指针指链表的指针,若链表有头结点则是链表的头结点的指针,头指针具有标识作用,故常用头指针冠以链表的名字。头结点是为了操作的统一、方便而设立的,放在第一元素结点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等),有头结点后,对在第一元素结点前插入结点和删除第一结点,其操作与对其它结点的操作统一了。而且无论链表是否为空,头指针均不为空。首元结点也就是第一元素结点,它是头结点后边的第一个结点。
7. 试述头结点,首元结点,头指针这三个概念的区别.
在线性表的链式存储结构中,头指针指链表的指针,若链表有头结点则是链表的头结点的指针,头指针具有标识作用,故常用头指针冠以链表的名字。头结点是为了操作的统一、方便而设立的,放在第一元素结点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等),有头结点后,对在第一元素结点前插入结点和删除第一结点,其操作与对其它结点的操作统一了。而且无论链表是否为空,头指针均不为空。首元结点也就是第一元素结点,它是头结点后边的第一个结点。
8. 在单链表和双向链表中,能否从当前结点出发访问到任何一个结点?
在单链表中不能从当前结点(若当前结点不是第一结点)出发访问到任何一个结点,链表只能从头指针开始,访问到链表中每个结点。在双链表中求前驱和后继都容易,从当前结点向前到第一结点,向后到最后结点,可以访问到任何一个结点。
9. 如何通过改链的方法,把一个单向链表变成一个与原来链接方向相反的单向链表
设该链表带头结点,将头结点摘下,并将其指针域置空。然后从第一元素结点开始,直到最后一个结点为止,依次前插入头结点的后面,则实现了链表的逆置
10. 设单链表结点指针域为next,试写出删除链表中指针p所指结点的直接后继的C语言语句。
q=p->next; p->next=q->next; free(q);
11. 有线性表(a1,a2,…,an),采用单链表存储,头指针为H,每个结点中存放线性表中一个元素,现查找某个元素值等于X的结点。分别写出下面三种情况的查找语句。要求时间尽量少。
(1)线性表中元素无序。(2)线性表中元素按递增有序。 (3)线性表中元素按递减有序。
设单链表带头结点,工作指针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->data<X ) p=p->next;
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<X) return(null); ∥查找失败
else return(p); ∥查找成功
13.按照下列题目中的算法功能说明,将算法描述片段中的错误改正过来。
(1) (4分)下面的算法描述片段用于在双链表中删除指针变量p所指的结点:
p^.rlink←p^.llink^.rlink;
p^.llink←p.^rlink^.llink
dispose(p);
(2) (6分)下面的算法描述片段用于在双链表中指针变量p所指结点后插入一个新结点:
new(q);
q^.llink←p;
p^.rlink←q;
q^.rlink←p^.rlink;
q←p^.rlink^.llink;
(1)前两个语句改为:
p.llink^.rlink<- p^.rlink;
p^.rlink^.llink<- p^.llink;
(2)后三个语句序列应改为:
q^.rlink<- p^.rlink;∥以下三句的顺序不能变
p^.rlink^.llink<- q;
p^.rlink<- q;
14.设双向循环链表中结点的数据域、前驱和后继指针域分别为data,pre和next,试写出在指针p 所指结点之前插入一s结点的C语言描述语句。
在指针p所指结点前插入结点s的语句如下:
s->pre=p->pre; s->next=p; p->pre->next=s; p->pre=s;
15. 一线性表存储在带头结点的双向循环链表中,L为头指针。如下算法:
(1)说明该算法的功能。(2)在空缺处填写相应的语句。
void unknown (BNODETP *L)
{ …
p=L->next; q=p->next; r=q->next;
while (q!=L)
{ while (p!=L) && (p->data>q->data) p=p->prior;
q->prior->next=r;(1) ______;
q->next=p->next;q->prior=p;
(2) ______;(3) ______; q=r;p=q->prior;
(4) ______;
}
}
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;∥后移指针,再将新结点插入到适当位置。