数据结构-线性表篇

数据结构-线性表篇:


内容:

  1. 思维导图(基于教材)
  2. 错题复盘+计算题(基于习题解析)
  3. 思考题

1.思维导图

在这里插入图片描述


2.错题复盘+计算题

2.1 顺序表中第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是(B)

A.110 B.108 C.100 D.120
解析:地址=100+2*4=108 || 元素跨度较小,可以累加,也可得到地址

2.2 在n个结点的顺序表中,算法的时间复杂度为O(1)的操作是(A)

A.访问第i个结点(1≤i≤n)和求第i个结点的直接前驱(2≤i≤n)
B.在第i个结点后插入一个新结点(1≤i≤n)
C.删除第i个结点(1≤i≤n)
D.将n个结点从小到大排序
解析:简化选项:A.查找 B.插入 C.删除 D.排序,顺序表按位置访问元素的时间复杂度为O(1),插入删除时间复杂度是O(n),排序通常为O(n^2)或O(nlog2n) --P48小结

2.3 将两个各有n个元素的有序表归并成一个有序表,其最少的比较次数是(A)

A.n B.2n-1 C.2n D.不确定
解析:一张表的最小元素都大于另一张表的最大元素时,每个元素都跟最大元素比

2.4 将两个各有n个元素的有序线性表归并成一个有序线性表,其最多的比较次数是(C)

A.n-1 B.n C.2n-1 D.2n
解析:两张表的元素,需要来回对比,再添加到新的线性表中,实质上遍历两张表,交替增加,又因为一次只移动一个指针,所以另一个链表无论怎样都会至少少走一步

2.5 在一个长度为n的顺序表中,在第i个元素(1≤i≤n+1)之前插入一个新元素时须向后移(B)个元素

A.n-i B.n-i+1 C.n-i-1 D.i
解析:从最后一个元素开始向后移,直到第i个元素,所以需要向后移n-i+1个元素

2.6 将长度为n的单链表链接到长度为m的单链表后的算法时间复杂度为(C)

A.O(1) B.O(n) C.O(m) D.O(m+n)
解析:要先找到表m的表尾,再将表n指针指向表尾即可完成链接,所以需要遍历表m

2.7 对于单链表表示法,以下说法错误的是(C)

A.数据域用于存储线性表的一个数据元素
B.指针域或链域用于存放一个指向本结点的直接后继结点的指针
C.所有数据通过指针的链接而组织成单链表
D.NULL称为空指针,它不指向任何结点,只起标记作用
解析:C说法不全面,结点包括数据域和指针域,正确说法是:所有结点(包括数据和指针)通过指针的链接而组织成单链表

2.8 访问单链表中当前结点的后继和前驱的时间复杂度分别是(C)

A.O(n)和O(1) B.O(1)和O(1) C.O(1)和O(n) D.O(n)和O(n)
解析:后继结点:后一个就是,所以时间复杂度是O(1) ;前驱结点:单链表没有指向前驱的指针,所以要访问前驱,就需要从头顺着链域访问,所以时间复杂度是O(n)

2.9 在具有n个结点的有序单链表中插入一个新结点并使链表仍然有序的时间复杂度是(B)

A.O(1) B.O(n) C.O(nlog2n) D.O(n^2)
解析:找插入位置,所以时间复杂度是O(n)

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

A.单链表 B.单循环链表 C.带尾指针的单循环链表 D.带头结点的双循环链表
解析:在末尾插入结点和删除结点需要修改相邻结点的指针域,所以需要找尾结点或尾结点的前驱结点,排除AB,带尾指针单循环链表在末尾插入结点只需要把尾指针指向新结点,时间复杂度是O(1),但是删除结点时,需要遍历链表,找到尾节点的前驱结点,时间复杂度O(n),而带头结点的双循环链表完美解决这个问题,可以直接定位到尾结点或尾结点的前驱结点,时间复杂度都是O(1)

2.11 在一个以L为头指针的单循环链表中,p指针指向链尾的条件是(A)

A.p->next=L B. p->next=NULL C. p->next->next=L D. p->data=-1
解析:循环链表的特点是最后一个结点的指针指向头结点,所以p指针指向链尾的条件就是p指针的指针域指向头结点L

2.12 若要在O(1)的时间复杂度上实现两个循环单链表的合并,合并后的新表头尾相接,则对应两个循环单链表各设置一个指针,分别指向(B)

A.各自头结点 B.各自尾结点 C.各自的首元结点 D.一个表的头结点,另一个表的尾结点
解析:解释请看思维导图关于循环链表的介绍,不再概述

2.13 下列关于链表说法错误的是(A)

A.对于循环单链表来说,从表中任一结点出发都能通过前后移动操作遍历整个链表
B.对一般单链表来说,只能从头结点开始才能遍历表中所有的结点
C.双向链表的特点是查找结点的前驱和后继都很容易
D.对双向链表来说,结点的存储位置既存放在其前驱结点的后继指针域中,也存放在后继结点的前驱指针域中
解析:循环单链表不能通过向前移动遍历链表,这种概念性问题,用排除法蒙对的概率更高

2.14 若对一个包含n(n>1)个结点的线性链表只做以下四种运算:删除首元结点、删除尾结点、在首元结点之前插入、在尾结点后插入,则最适合的存储结构是(C)

A.只有头结点指针没有尾结点指针的循环单链表
B.只有尾结点指针没有头结点指针的非循环双链表
C.只有头结点指针没有尾结点指针的循环双链表
D.既有头结点指针又有尾结点指针的循环单链表
解析:A链表在对尾结点操作时,需要遍历链表,时间复杂度为O(n);B链表在对头结点操作时,需要向前遍历链表,时间复杂度也为O(n);C链表四种操作的时间复杂度都是O(1);D链表删除尾结点时,需要遍历链表找到尾结点前驱结点,时间复杂度为O(n)

2.15 设一个非空的带头结点的循环单链表的头指针为L,当L->next->next->next=L时,链表长度可能为(C)

A.0 B.1 C.2 D.3
解析:据2.11可得空循环单链表的条件是L->next=L,所以L->next是首元节点,L->next->next是第二个结点,L->next->next->next指向头结点,所以链表有两个结点

2.16 在一个长度为n(n>1)的单链表中,设置了头指针和尾指针。以下(B)操作的执行效率与n有关

A.删除单链表的首元结点       B.删除单链表的尾结点 
C.在首元结点前插入一个新元素    D.在尾节点后插入一个新元素
解析:链表在对尾结点操作时,需要遍历链表,找到尾结点的前驱结点,时间复杂度为O(n),剩下的操作时间复杂度是O(1),跟n无关

2.17 在长度为n的顺序表的表尾插入一个新元素的时间复杂度为(B)

A.O(n) B.O(1) C.O(n^2) D.O(log2n)
解析:直接插入,时间复杂度为O(1)

2.18 带头结点的循环双链表L为空的条件是(D)

A.L->prior==L && L->next == NULL
B.L->prior ==NULL && L->next ==NULL
C.L->prior ==NULL && L->next ==L
D.L->prior ==L && L->next ==L
解析:据2.11得空循环单链表的条件是头结点的后继指针指向自身,思路发散一下,再加上头结点的前驱指针指向自身,不就是空循环双链表的条件

2.19 下列关于单链表头结点的叙述中,错误的是(D)

A.若在头结点中存入链表长度值,则求链表长度运算的时间复杂度为O(1)
B.在链表的任何一个元素前后进行插入删除操作可用一致的方式进行处理
C.加入头结点后,代表链表的头指针不会因为链表为空而改变
D.加入头结点后,在链表中查找运算的时间复杂度为O(1)
解析:加入头结点后,在链表中查找运算仍然需要遍历链域,时间复杂度是O(n)

2.20 已知L是带头结点单链表的头指针,则从链上删除首元结点的语句是(B)

A.q=L;L=L->next;
B.q=L->next;L->next=q->next;
C.q=L;L=L->next->next;
D.L->next=L;
解析:删除首元结点需要把头指针修改为指向首元结点的下一个结点

2.21 设rear是指向非空带头结点的循环单链表尾结点的指针。若想删除链表的首元结点,则应执行(D)操作

A.s=rear;rear=rear->next;delect s;
B.rear=rear->next;delect s;
C.rear=rear->next->next;delect rear;
D.s=rear->next->next;rear->next->next=s->next;delect s;
解析:简略版:rear是带头结点循环单链表的尾指针,计划删除首元结点。所以rear->next是尾结点,rear->next->next指的是首元结点,跟上题一样,只需要把尾指针指向首元结点修改为指向首元结点的下一个结点,也就是rear->next->next=rear->next->next->next,D选项用了s代表首元结点,原理是一样的

2.22 对于双向链表和单链表,在两个结点之间插入一个新结点需修改的指针分别为(D)个

A.3、2 B.4、1 C.3、1 D.4、2
解析:双向链表:修改前一个结点的后继指针指向新结点,后一个结点的前驱指针指向新结点,新结点的前驱指针指向前一个结点,后继指针指向后一个结点
单链表:前一个结点的后继指针指向新结点,新结点的后继指针指向后一个结点

2.23 下面关于线性表的一些说法中,正确的是(C)

A.对一个设有头指针和尾指针的单链表执行删除最后一个元素的操作与链表长度无关
B.线性表中每一个元素都有一个直接前驱结点和一个直接后继结点
C.为了方便插入和删除数据,可以使用双向链表存放数据
D.取线性表第i个元素的时间与i的大小有关
解析:A.要是认真看前面的题,就知道错哪了,我懒得再复制了,自己往前翻
B.线性表中第一个元素没有直接前驱结点,最后一个元素没有直接后继结点
D.往上看看思维导图,线性表是不是有分成两类,线性表要是用顺序存储,那读取第i个元素的时间复杂度就是O(1)了,跟i的大小没关系

2.24 若链表中最常用的操作是在最后一个元素之后插入一个元素和删除第一个元素,则选择(D)是最节省时间

A.单链表 B.仅有头指针的循环单链表 C.双向链表 D.仅有尾指针的循环单链表
解析:ABC.在最后一个元素之后插入一个元素要遍历才能找到插入位置,时间复杂度是O(n)

2.25 设一个长度为n(n>1)的循环单链表,若从表中删除首元结点的时间复杂度为O(n),此时采用的循环单链表结构是(A)

A.只有头指针,没有头结点
B.只有尾指针,没有头结点
C.只有尾指针,带头结点
D.只有头指针,带头结点
解析:没有头结点的话,头指针直接指向首元结点,要删除首元结点需要找到它的前驱结点,所以要找最后一个结点,排除CD,参考2.21明显可以看出来时间复杂度O(1),排除B

2.26 已知两个长度分别为m和n的升序链表,若将它们合并为一个长度为m+n的降序链表,则最坏情况下的时间复杂度是(D)

A.O(n) B.O(mn) C.O(min(mn)) D.O(max(mn))
解析:如果要求合并后仍按照原序排列,最好的情况是其中一张有序表的所有元素都小于另一张有序表的所有元素,此时只需要比较min(m,n)次就可完成,最坏情况是两个表元素交替增加,时间复杂度为O(m+n);如果要求合并后仍按照逆序排列,则无论情况好坏,时间复杂度为O(m+n)。选项中没有提供此答案,可以通过分析选择一个与此答案相符的选项,在具体分析时,假设m>n,然后分以下两种情况讨论:
1.如果m非常接近于n,则O(m+n)接近于O(m)或O(n),而O(m
n)接近于O(n^2),因此有O(mn)>>O(m+n),选项B不正确
2.如果m>>n,则O(m+n)>>O(n),而O(min(m
n))接近于O(n),因此有O(m+n)>>O(min(mn)),选项AC都不正确
对于以上两情况,选项D都成立。当m非常接近于n时,O(m+n)接近于O(m)或O(n),也接近于O(max(m
n));当m>>n时,O(m+n)也接近于O(max(m*n))

2.27 已知指针h指向一个带头结点的非空循环链表,结点结构为(data,next),其中next是指向直接后继结点的指针,p是尾指针,q为临时指针,现要删除该链表的第一个元素,正确的语句序列为(D)

A.h->next=h->next->next;q=h->next;free(q);
B.q=h->next;h->next=h->next->next;free(q);
C.q=h->next;h->next=q->next;if(p!=q) p=h;free(q);
D.q=h->next;h->next=q->next;if(p==q) p=h;free(q);
解析:当删除的元素时链表最后一个元素时,还需要同时修改尾指针,使其指向头结点


3.思考题

  1. 试写一算法,实现对单链表的就地逆置
    思路:利用前插法创建链表的思想,先插入的结点为表尾,后插入的结点为表头,所以遍历单链表,将结点用前插法依次插到头结点的后面,就可以完成单链表的就地逆置了
    1.p指向首元结点,待会遍历就行,然后把头结点的指针域设为空,用来存放逆置元素
    2.遍历链表,p存在,在插入前,为防止丢失后继结点,q指向p的后继结点,用来保存
    3.P结点插在头结点的后面之后,再指向新的结点,又回到第2步,循环,直到遍历结束
    在这里插入图片描述
  2. 假设以两个元素依值递增有序的线性表A和B分别表示两个集合(即同一表中的元素值各不相同),现要求另辟空间构成一个线性表C,其元素为A和B中元素的交集,且表C中元素也依值递增有序。试对单链表编写求C的算法。(也可利用线性表A的空间实现)
    思路:线性表A和B都是有序集合,那么不需要再进行额外的排序,用通过对比,将交集结点用尾插法插入线性表C
    1.遍历线性表B,将其与线性表A每个元素进行比较,相同就插入到线性表C
    在这里插入图片描述
  1. 实现单链表的递增排序(选做)
    思路:用了冒泡排序实现题目要求,用q代表p之后的元素,两者进行比较,如果p>q的值那么就交换,每趟都会将最大的放到最后
    在这里插入图片描述
  2. 删除单链表中的重复值、使每个数值都不同(选做)
    思路:根据上题改编而来,也是用冒泡排序
    在这里插入图片描述
    别问我具体思路和步骤,我当时手写的实验报告,现在只能找到演算的代码,勉强倒推思路,已经忘记怎么完整叙述原理过程了-_-

  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值