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.在学习这一段代码,是怎么逆序的这一部分有一点难懂,需要一边画图,一边理解。
原文地址:https://www.cnblogs.com/linshuxin1761/p/10626495.html