1.本周学习总结
1.1思维导图
1.2.谈谈你对线性表的认识及学习体会
这周学习了线性表,它有两种存储方式,一种顺序储存,用的是数组,另一种是链式存储,用的是链表。恍惚想到上学期的课设,也是两种方法完成,一种用数组,一种用链表。
线性表是一对一的结构,可以作为存放数据的容器,而且可以用它的基本操作来完成更复杂的功能。
在完成pta时,顺序表部分的比较熟悉,做到链式的时候,因为对链表不是很熟悉,做得一脸懵逼,一边写一边看书或者问舍友
然后花了一个晚上把线性表重新看了一遍,终于比较懂它在讲什么了,莫名欣慰
2.PTA实验作业
2.1.题目1: 顺序表删除重复元素
设计一个算法,从顺序表中删除重复的元素,并使剩余元素间的相对次序保存不变
2.1.1设计思路(伪代码)
定义变量i,j=0,i当data数组的下标,j当重构data后的下标
定义一个hash数组,并且初始化为0
遍历整个顺序表
将L->data[i]的值作为hash数组的下标,并且统计其出现的次数
if L->data[i]所在的下标i对应出现的次数是第一次
将这个值存入重构的data数组里,其下标j加一
让L->length为j,即它的新长度
2.1.2代码截图
2.1.3本题PTA提交列表说明
Q1:部分正确是空表这个测试点错了,题目没有要求空的时候要给出什么提示,但是我加了个输出error就错了
A1:修改了一下输出线性表的函数就过了
Q2:在老师讲这道题之前,就是用的是哈希数组来查找,但是我的代码好像没有真正改到L,但它还是让我过了
A2:老师讲了之后,并且在舍友的发现下,发现我的代码是错的(虽然它过了),并对它进行了修改
2.2 题目2:链表倒数第m个数
已知一个带有表头节点的单链表,查找链表中倒数第m个位置上的节点
2.2.1设计思路
定义两个LInkList类型的指针,一个为pre作为遍历L的指针,一个为p作为指向第m个元素的指针,定义整型变量i,用来记数
pre指向首结点,q为空
while p还没到尾部并且传入的m大于0 do
记数的i开始自增
if 刚好移到第m个数
q开始从首结点移动
if 移到第m个数之后
q开始指向下一个结点,即往后移
pre在循环过程中,一直往后移
end while
if q为空,即传入的m无效
返回-1
else
返回q指向的data的值
2.2.2代码截图
2.2.3本题PTA提交列表说明
Q1:一开始的运行超时是while里面忘记让用来遍历的pre指针往后移了,导致while出不来,就运行超时了,一个低级错误
A1:添加了一个pre=pre->next
Q2:然后问题又来了,出现了段错误,其实一直不是很懂段错误是什么样的错误,好像有很多种,栈溢出或者数组越界什么的,我这里的错误应该是添加的pre=pre->next放错位置了,一进while里,还没记数就让它往后移了
A2:于是我把它移到while里的最后一句,其实之前对在循环里面的语句顺序一直不以为意,现在发现还是差很多的
Q3:然后是部分正确,有个位置无效的测试点过不了假如它的m小于0,还是可以进我的while里并且也能让p往后移,这样就会导致答案错误了
A3:于是在while的判断条件里加了个m>0,这样的话,m如果小于0,就直接到判断q是否为空,直接返回-1了
2.3 题目3:有序链表合并
已知两个递增链表序列L1与L2,2个链表都是带头结点链表。设计函数实现L1,L2的合并,合并的链表仍然递增有序,头结点为L1的头结点。 合并后需要去除重复元素。
2.3.1设计思路
定义LinkList类型的指针,Ptr1为L1的遍历指针,Ptr2为L2的遍历指针,temp为保存L1的指针
Ptr1指向L1的首结点
Ptr2指向L2的首结点
重构L1,并且用temp保存L1
while Ptr1&&Ptr2 do
if Ptr1指向的data大于Ptr2指向的data
temp的后继结点指向Ptr1,Ptr1继续往后移
else if Ptr1指向的data小于Ptr2指向的data
temp的后继结点指向Ptr2,Ptr2继续往后移
else
temp的后继结点指向Ptr1,Ptr1,Ptr2一起往后移
temp往后移
end while
if Ptr1
将Ptr1剩下的接到temp的后继结点上
if Ptr2
将Ptr2剩下的接到temp的后继结点上
2.3.2代码截图
2.3.3本题PTA提交列表说明
Q1:编译错误,又是简单的小问题,不小心把Ptr的后继结点指向了Ptr的data了,一开始还没反应过来,连交了几次
Q2:部分正确,就只有那个空表的测试点过了, 另外两个都运行超时了,做的时候对链表还不是很了解,就是看着书,用尾插法把符合的接到L1上,但是好像和书上的代码不太一样,导致运行超时了
A2:后来尝试着注释掉几个语句,就一不小心就过了,幸福来得太突然了。我注释掉的语句是让temp等于Ptr,像尾插法那样,后来发现这样做的话,temp就会一会指这个,一会指那个的,整个都乱掉了
3.阅读代码
找一份优秀代码,理解代码功能,并讲出你所选代码优点及可以学习地方。主要找以下3种类型代码:
读源码,如从python或C++中找用线性表封装的库源码,分析代码功能及可以学习地方。
考研题种关于线性表内容。可以找参加过考研的学长学姐拿。尤其是想要考研同学,可以结合本章内容,用考研题训练学习。
ACM、PTA天梯赛、leecode面试刷题网站,找线性表相关题目阅读分析。
请按照下面内容填写代码阅读内容。请未必认真完成,如果发现应付,没有介绍代码思路、体会等扣分。
3.1 题目
集合A比较与集合B的交集
3.2 解题思路
将要比较的集合传入函数,另一个是用来返回状态的类型//(用于判断contains)
获得当前对象的所有函数
定义r=0,用来遍历元素,定义w=0,用来标记两个集合公共元素的个数
定义状态为false,用来返回是否有交集的状态
遍历A集合
判断B集合中是否包含集合A中的当前元素//(用contains的判断,如果返回true则有包含集合B)
if 包含则直接保存
将数值复制给数组,让w++
if r的值比size小//(contains抛出错误)
复制剩余的元素
调用system.arrraycopy(第一个参数为源数组,第二个参数为源数组要复制的起始位置,第三个参数为目的数组,第四个参数为目的数组放置的起始位置,最后一个参数为复制的长度)
w为当前集合A的长度
end if
if 集合A的大小发生变化//(w不等于size,即有交集)
遍历交集里的元素
将null赋值给元素
记录集合中元素的改变
设置当前数组的大小//size=w;
状态改为true
end if
返回状态
3.3 代码截图
3.4 学习体会
找这份代码找了挺久的,也不知道找什么,看了力扣的线性表题,中等题和困难题大部分都没有题解,就放弃了
后来去找list的源代码,找到了这个找交集的,刚好和pta考试那个有点像,那个是用链表做的,这个用的是数组
这个源代码调用了一些其他函数,例如contains和arraycopy,如果没有去搜一下还真不知道在表达什么
发现又很多步骤都有已经写好的函数可以调用,只要知道它怎么传参,就差不多会用了
我觉得这个代码值得我学习的有
清除的这个步骤,它没有用移动数组来清除,而是直接将null赋值给它了
在判断集合A是否包含集合B时,不是用两重遍历来判断,而是调用了函数来实现,时间复杂度为O(n),这个函数可以学习下来