zoukankan      html  css  js  c++  java
  • 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,很清楚地将两个情况划分处理。当然值得学习的还有变量名、函数名和结构题名的定义以及函数的运用都很恰当。通过对考验题目的学习能使我们更好地掌握知识的深浅度,锻炼解读代码的能力,提前熟悉考试内容,为接下来的题目复习打下基础。

  • 相关阅读:
    django学习之命令
    832. 翻转图像
    JUC线程池深入刨析
    CountDownLatch、CyclicBarrier、Samephore浅谈三大机制
    深入理解Atomic原子类
    浅谈volatile关键字
    web应用启动的时候SpringMVC容器加载过程
    MySQL锁机制
    TCP拥塞控制
    HTTPS的加密流程(通俗易懂,不可错过)
  • 原文地址:https://www.cnblogs.com/blsn/p/10604338.html
Copyright © 2011-2022 走看看