DS博客作业02--线性表
1.本周学习总结(2分)
1.1思维导图
1.2.谈谈你对线性表的认识及学习体会。
- 对于线性表其实在上学期就已经接触过了,但在上学期的学习中也只是简单的接触,并没有比较全面的学习,pta题目也做得比较少,在我看来和新的知识比较并没有太多的区别,还是要花费时间去理解,有时还会发现自己以前的理解是错误的,在运用链表完成PTA题目中总算是一不小心就写成野指针,忘记判断空链表的情况,感觉需要一个慢慢过渡的阶段。还有对线性表还是很不熟悉,往往一个小细节上的错误,找了很久都发现不了。
2.PTA实验作业(6分)
2.1.题目1:6-3 jmu-ds- 顺序表删除重复元素(顺序表)
2.1.1设计思路(伪代码)
设计思想:先对顺序表进行排序,再进行重构,该元素如果与下一个元素相等跳过,保证没有重复,又有序。
伪代码:
//先进行排序
for j=0 to L->length
for i=0 to L->length
if L->data[i]<L->data[i-1] then//后一个小于前一个
//进行交换
temp=L->data[i]
L->data[i]=L->data[i-1]
L->data[i-1]=temp
end if
end for
end for
//再进行重构
for i=1 to L->length
与前一个元素相等跳过,不相等进行下面操作
L->data[k]=L->data[i],用k计算个数,k从1开始
end for
//判断空表
如果不是空表,长度等于k
2.1.2代码截图
2.1.3本题PTA提交列表说明。
- 问题1:太久没使用排序法,在使用冒泡排序法的时候只有一重循环,导致数据排序不正确
解决:使用双重循环嵌套,使数据能正确排序 - 问题2:在空链表的测试点上一直过不去,在输出的部分修改了几次,都没有任何作用
解决:不是输出的问题,是链表长度的问题,当为空链的时候,链表长度应为0,因为重构的原因,不小心把长度定为从1开始,导致测试点过不了。
2.2 题目2: jmu-ds-链表倒数第m个数(单链表)
2.2.1设计思路(伪代码)
设计思想:在一条链上放两个指针,它们的间隔为m,如果一个指针指到尾,另一个指针的所指的位置就是倒数第m个数,这个方法可以避免多次遍历,减少时间复杂度。
伪代码:
定义LinkList型指针head,last,两个指针均指向头结点
if m取小等于0(无效位置) then
返回 -1
for i=0 to m(使两个指针相隔m)
last=last->next//指针last往下移
if last->next==NULL//即L的长度小于m
返回 -1
end for
while last->next不为空 do
指针head与指针last同时向下移动
end while
返回 head->next->data的值
2.2.2代码截图
2.2.3本题PTA提交列表说明
- 问题1:在位置无效的一个测试点过不了
解决:没有考虑到无效的位置可能是负数的可能性,只考虑到会不会超过数据个数 - 问题2:指针的位置没有控制好,循环到野指针去了
解决:控制一下循环,如果遇到last->next==NULL就停止
2.3 题目3:两个有序序列的中位数(有序表)
2.3.1设计思路(伪代码)
设计思路:先对两组数据进行二路归并,使之成为一条有序的链,然后找出中位数。
伪代码:
主要是双链合并,和寻找中位数
1.先进行双联合并,在L1上进行操作
//如果L1本为空链,L2直接接到L1后面
L1->next=L2->next
//如果L2本为空链
return
//在L1上设两个指针一前一后head和last
head=L1 last=L1->next
//在L2上设1个指针p
p=L2
//随着指针的移动,把L2上比last所指元素小的数插到head和last之间
if p所指比last所指的小 then
temp=p
p=p->next
head->next=temp
temp->next=last
head=head->next//保持head与last是相邻的
end if
else
head和last继续移动
end else
//如果last指向NULL,而L2中还有数未遍历完,把剩余的接到L1后面
last->next=p
2.寻找中位数(第n个数)
for i=0 to n
L=L->next
end for
输出L所指的元素
2.3.2代码截图
2.3.3本题PTA提交列表说明
- 问题1:把重复的数据去掉了,没有认真阅读题目的意思。
解决:把在双链合并的过程中遇到相等的数还是插入L1,而不是L2继续移动而不插入。
3、阅读代码(2分)
找一份优秀代码,理解代码功能,并讲出你所选代码优点及可以学习地方。
3.1 题目
[LeetCode] Palindrome Linked List 回文链表
3.2 解题思路
- 快慢指针找中点的原理:fast和slow两个指针,每次快指针走两步,慢指针走一步,等快指针走完时,慢指针的位置就是中点
- 首先,find mid node 使用快慢指针找到链表中点。 然后,reverse 逆序后半部分,使用头插法,将后半部分的数据进行倒置。 最后,check,head和pre两个指针同时进行遍历比较是否相同。如果相同返回true,有不同返回false
3.3 代码截图
3.4 学习体会
- 判断回文的题目我们在上学期的学习中就有遇到过,像一个数判断回文,先把数除以10然后所得余数乘10,每次累加每次乘十进行倒置,后来学数组找中点通过下标进行比较。
而这道题是链表,明显以前的方法都用不上了,但是倒置的思想还是没有变的,对链的后半部分进行倒置。 - 优点:1.使用了快慢指针,可以减少遍历,很快的找到中点,时间复杂度大大减少,不禁让我联想到找倒数第m个数所使用的双个指针的方法
2.时间复杂度降低的同时,代码量也不多,还使用(? :)这样的符号,使代码更加简便 - 学习到:
1.学会了运用快慢指针找中点,减少了遍历的次数,甚至以后在寻找三分之一,多分之一的也可以依样画葫芦。
2.在代码中也复习了一下判断语句的一个简便符号(? :),可以减少代码量,比较简便
3.学到nullptr,这个c++中空指针类型的关键字,可以被转换成任意其他指针,其用法和直接用字面值0是一样的。
4.在学习这一段代码,是怎么逆序的这一部分有一点难懂,需要一边画图,一边理解。