DS博客作业02--线性表

1.本周学习总结

1.1思维导图

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代码截图

2.1.3本题PTA提交列表说明


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代码截图

2.2.3本题PTA提交列表说明


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代码截图

2.2.3本题PTA提交列表说明


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 代码截图


3.4 学习体会

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

原文地址:https://www.cnblogs.com/blsn/p/10604338.html