DS博客作业02--线性表

本文总结了线性表的相关知识,包括线性表的特点、存储方式及其应用。介绍了顺序表和链表的概念,并通过pta练习题加深理解。同时,详细记录了PTA实验作业中的设计思路、代码实现及常见问题解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.本周学习总结

1.1思维导图

1475110-20190330155732523-741166771.png

1.2.谈谈你对线性表的认识及学习体会

  • 本章主要学习了线性表的相关知识,线性表是具有相同特性的数据元素的一个有限序列,是一种最常用的数据结构。线性表中的元素呈现线性关系,其具有的特点是有穷性、一致性、序列性。线性表有多种存储方式,顺序存储结构的是顺序表,借用数组实现;链式存储结构的是链表,借用结构体和指针实现,其中还分为单链表,双链表,循环链表。有序表是一种特殊的线性表,它的所有元素以递增方式排列,也作为重要题型出现。
  • 在做线性表的pta练习题时,总结了以下需要注意点:链表头结点的next才是第一个数据,处理结点时需要用next的数据才能得到前驱指针,循环条件对指针的判断需要注意是否是野指针。通过对线性表的学习,懂得了像头插法、尾插法、二路归并法等多种构建方法,使对多个数据组进行处理的问题更加轻松高效;同时还更熟悉了时间复杂度和空间复杂度的运算,能更好地通过改变运算过程提高运行效率,这也是学习数据结构最重要的目的。

2.PTA实验作业

2.1.题目1:

2.1.1设计思路

List MakeEmpty()
    定义结构体指针L,并动态分配空间 
    L的最后一个元素位置Last为-1
    返回指针L

Position Find( List L, ElementType X )
    循环遍历链表,若数据与X相等,则返回位置i 
    否则返回ERROR

bool Insert( List L, ElementType X, Position P )
    if L->Last==MAXSIZE-1 then //空间已满        
        输出"FULL"     
        返回false
    else if P<0或P>L->Last+1 then //参数P指向非法位置
        输出"ILLEGAL POSITION"  
        返回 false 
    end if 
    for i=L->Last+1 to i>P do i-- //数据位置后移 
        后一个数据等于前一个数据 
    end for 
    P位置元素等于X 
    L的最后一个元素位置Last加一
    返回true

bool Delete( List L, Position P )
    if P<0||P>L->Last then //参数P指向非法位置 
        输出"POSITION %d EMPTY",P
        返回 false
    end if 
    从位置P开始的元素位置前移
    L的最后一个元素位置Last减一 
    返回true

2.1.2代码截图

1475110-20190330193816527-957653101.png

2.1.3本题PTA提交列表说明

1475110-20190330193826085-1003389007.png
Q1:链表的定义和使用时容易出错
A1:在定义指针时要区分typedef结构体和typedef结构体指针的使用
Q2:题目要求较为繁杂,涉及的要求点较多
A2:先读懂题意,将每个要求分别设计代码,再进行简单的联系

2.2.题目2:链表倒数第m个数

2.2.1设计思路

定义遍历链表的指针p和s 
定义length为链表的长度
遍历各节点累加求长度length
如果序数大于长度则返回-1
定义i为length-m+1
while s->next do //遍历找位置
    如果i是0则返回该节点的数 
    i--
    s指向下一个结点 
end while 

2.2.2代码截图

1475110-20190326223548583-1297186641.png

2.2.3本题PTA提交列表说明

1475110-20190327165336090-2075090470.png
Q1:部分正确的错误原因是段错误
A1:指针在定义和应用时容易忘记* 的使用和野指针的判断
Q2:计算倒数序数时需要知道是否加一
A2:可以纸上自行模拟,也可以尝试加一和不加一的两种方法得到结果
不同解法:

  • 方法一:新建一个链表把原链表通过头插法倒置,然后直接找第m个数。这种方法增加了空间复杂度,却没有减少时间复杂度,所以不采用。
  • 方法二:定义两个指针,第一个指针指向头结点,然后向后移m个位置,再让第二个指针指向头结点,同步向后移动,保持m的差距,当第一个走完链表时,第二个指针所指位置就是倒数第m个位置。这种方法减少了时间复杂度,没有增加空间复杂度,可以采用。

2.3.题目3:有序链表合并

2.3.1设计思路

定义p1和p2分别指向头结点L1,L2
定义p用来指向新建结点 
while p1->next且p2->next do 
    if p1->next->data大于p2->next->data then //p2数据较小时插入到p1的结点 
        新建链表结点p插入到p1的下一个 
        p1=p1->next
        p2=p2->next
    else if p1->next->data小于p2->next->data then //p1数据较小时跳过p1的结点 
        p1=p1->next
    else  //数据相等时跳过p2的结点 
        p2=p2->next;
    end if  
end while 
while p2->next do //将p2剩余数据插入到p1末尾 
    新建链表结点p插入到p1的下一个 
    p1=p1->next
    p2=p2->next
end while

2.3.2代码截图

1475110-20190327220222970-1282928121.png

2.2.3本题PTA提交列表说明

1475110-20190327220514490-1081016268.png
Q1:部分正确的错误原因是段错误
A1:使用p->next->data在末尾指向时会造成野指针,所以需要改变判断条件
Q2:刚开始用p->data直接进行数据操作,但在插入新结点时无法得到前驱
A2:后来改用p->next->data进行数据操作,插入新结点时的前驱就是p结点,方便插入也方便删除
Q3:这道题可以通过L2上的结点直接接入到L1中,能减少一定的空间复杂度
A3:我想保留这个L2的完整性,所以不采用这个方法

3、阅读代码

3.1 题目

两个有序的单链表ha和hb,请判断链表a是否包含在链表b内,是则返回1,否则返回0。

3.2 解题思路

构建两个有序链表存储两个数据组“1 3 5”和“1 2 3 4 5”。在inclusion函数中用了递归的方法,首先由头结点指向链表的开始节点,只有当pb的data比pa的data小才会有接下来的工作,如果pb最小的都要比pa大那么就不是包含关系了,所以循环条件为pa->data>=pb->data且pb不为NULL;而递归结束的条件是当两个数据不相等的时候,原因是只要一个不相等就不满足题意;当遍历完链表中的所有数据且都相等时,则用pa为NULL的判断条件来确定遍历完成,返回1。

3.3 代码截图

1475110-20190330224413624-1583972460.png
1475110-20190330224417776-488184629.png

3.4 学习体会

这道题目是清华大学1994年的考研题,题意清晰,难度不大。我认为这个解法中值得学习的地方就是运用了递归的方法,通过递归来判断pa中的元素是否在pb中都出现,只要有一个没有就能返回0且结束递归,若遍历完pa就能返回1,很清楚地将两个情况划分处理。当然值得学习的还有变量名、函数名和结构题名的定义以及函数的运用都很恰当。通过对考验题目的学习能使我们更好地掌握知识的深浅度,锻炼解读代码的能力,提前熟悉考试内容,为接下来的题目复习打下基础。

1475110-20190331090757282-18581095.png

转载于:https://www.cnblogs.com/blsn/p/10604338.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值