zoukankan      html  css  js  c++  java
  • DS博客作业02--线性表

    1.本周学习总结

    1.1思维导图

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

    (1) 首先链表我上学期已有一定的基础,所以学起来没有太大的困难,但是解决问题时不够老道,
    没有写出的代码时间复杂度不是太好,和老师举例的算法有明显差距,这方面还需多积累。
    (2) 其次链表操作会涉及到指针,指针的用法又可以相当巧妙,让本来复杂的问题变简单,
    但是用不好可能会留下各种小bug,难以查找,甚至崩溃。所以要多多领悟总结。
    

    2.PTA实验作业

    2.1.题目1:6-2 jmu-ds-有序表插入数据

    实现在顺序表中删除某个区间数据。需要实现下述的三个函数完成该功能。
    实现函数:
    CreateSqList:创建有序表,连续输入n个正数存入有序表中。L表示顺序表指针,n表示输入数据个数。
    InsertSq(SqList *&L,int x):顺序表L中插入数据x。
    DispSqList:输出顺序表L中所有数据。数据间空格隔开,尾部不能有空格。
    

    2.1.1设计思路

    • void CreateSqList(SqList &L, int n)创建有序表
            用new分配内存给L	
            L->length赋值为n,n为输入数据长度
    	if  (n小于等于最大值50)  then       
    	{
    		输出“大于数组长度”	
        }
            end if
    	if (n等于0) then
    	{
    		输出 "error"
                    并且退出
    	}
    	else if  (n大于0) then
    	{
    		for (i 从0开始循环到 L->length-1)
    		{
    			输入数据到 L->data[i]中
    		}
    	}
    	else 如果n<0为不合法
    	{
    		输出 "小于0 error"
    	}
           end if
    
    • void InsertSq(SqList &L, int x)顺序表L中插入数据x
      遍历找到插入点然后后面元素后移
             定义变量flag记录插入位置
    	for  (i 从 1 循环到 L->length=1	)
           {
    		if  (L->data[0] 大于 x)  then     //插入头
    		{
    			把标记flag = 0意为插入头
    			退出循环		
            }
    		else if ( L->data[L->length - 1] 小于 x) 说明要插入尾
    		{
    			把标记flag = L->length - 1意为插入尾
    			退出循环
    		}
    		else if    L->data[i] 大于x并且L->data[i - 1] 小于x    then   
    		{
                            找到中间插入点赋给flag
    			flag = i
    		}
            end if
    	}
            end for
    	if   (flag 等于 L->length - 1) then
    	{
    		L->data[L->length] = x     //在尾部插入x
    	}
    	else
    	{
    		for  (i = L->length to flag)
    		{
    
    			L->data[i] = L->data[i - 1]   //后移
    		}
            end for
    		L->data[flag] = x   //插入x
    	}
        end if
    	长度L->length加1
    
    • void DispSqList(SqList L)输出顺序表L中所有数据。数据间空格隔开,尾部不能有空格
    	for  (从i = 0 循环到 L->length)
    	{
    		输出 L->data[i]
    		if   i 小于 L->length - 1 then   //结尾无空格
    		{
    			输出空格
    		}
    	}
    

    2.1.2代码截图




    2.1.3本题PTA提交列表说明

    • Q1:代码考虑不周全,插入结尾时会插入到前一个
    • A1;对插入结尾单独判断

    2.2.题目2:6-4 顺序表操作集

    本题要求实现顺序表的操作集。
    

    2.1.1设计思路(伪代码)

    (1) List MakeEmpty():创建并返回一个空的线性表;

    List MakeEmpty()
    {
    
        声明结构体指针q,用malloc分配内存;
    	给q->Last 赋值为 -1表示为空
    	返回 q;
    }
    

    (2) Position Find( List L, ElementType X ):返回线性表中X的位置。若找不到则返回ERROR;
    for循环遍历顺序表查找X的位置,找不到返回ERROR

    Position Find(List L, ElementType X)
    {
    	for (从0开始循环到顺序表最后L->Last)
    	{
    		if (如果L->Data[i] 等于 X)
    		{
    			返回位置i;
    		}
    	}
    	如果找不到返回 ERROR;
    }
    

    (3)bool Insert( List L, ElementType X, Position P ):将X插入在位置P并返回true。若空间已满,则打印“FULL”并返回false;如果参数P指向非法位置,则打印“ILLEGAL POSITION”并返回false;
    先判断是否合法,然后for循环查找插入位置,然后把插入位置之后的元素后移,把元素插入

     bool Insert(List L, ElementType X, Position P)
    {
    	if (如果最后元素位置L->Last 等于最大位置MAXSIZE-1)
    	{
    		输出( "FULL")
    		返回 false
    	}
    	if (如果P小于0或者大于最后元素位置)
    	{
    		输出( "ILLEGAL POSITION");
    		返回 false;
    	}
    	if (如果P 小于等于 元素最后位置L->Last)需要移动元素 
    	{
    		for (i从最后位置L->next+1的位置循环到p)
    		{
    			L->Data中的i-1位置的元素移到i位置 
    		}
    		通过循环后移结束后把L->Data[P]赋值为X
    		L->Last最后元素位置加一 
    	}
    	else 不需要移动 
    	{
    		通过循环后移结束后把L->Data[P]赋值为X
    		L->Last最后元素位置加一 
    	}
    		返回true 
    }
    

    (4) bool Delete( List L, Position P ):将位置P的元素删除并返回true。若参数P指向非法位置,则打印“POSITION P EMPTY”(其中P是参数值)并返回false。

    bool Delete(List L, Position P)
    {
    	if (如果p不合法)
    	{
    		输出("POSITION %d EMPTY",P);
    		返回 false;
    	}
    	for (从头遍历一遍顺序表)
    	{
    		if (如果目标P 不等于当前i)
    		{
    			就把L->Data[j++]赋值为L->Data[i]重构顺序表 
    		}
    	}
    	最后顺序表的最后元素位置L->Last减一
    	返回 true
    }
    

    2.1.2代码截图


    2.1.3本题PTA提交列表说明


    Q1:使用了new,但是题目是gcc编译
    Q2:在尾部删除时没有考虑到
    Q3:输出不对等小问题

    2.3.题目3:7-2 一元多项式的乘法与加法运算

    设计函数分别求两个一元多项式的乘积与和。

    2.3.1设计思路(伪代码)

    结构体定义

    typedef struct equation
    {
    	定义int类型系数 number;
    	定义int类型次方 power;
    	定义equation* 指针next; 
    }EQU;//equation方程 
    

    (1) 建链表(比较简单不详细介绍)

    void CreateList(EQU *&head,int &count)
    {
            用new分配内存
        	用for循环不断输入
            尾插法建链表
    }
    

    (2) 多项式加法
    在循环中相同次方的系数相加或者不相等就把大的赋值到addresult中,直到两个链表遍历完毕

    void EquationAdd(EQU* const &head1, EQU* const &head2,EQU* &addresult)
    {
    	用new分配内存,具体细节不表 
    	声明EQU指针q1来代替head1, q2来代替head2,temp为临时,p来代替addresult
    	for (如果q1或q2不为空)
    	{
    		用new为temp分配内存 
    		if (如果q1和q2都不为空)
    		{
    			if (如果q1->power 等于 q2->power)就合并 
    			{
    				把temp->power 赋值为q1->power
    				把temp->number 赋值为 q1->number + q2->number
    				q1和q2都等于下一个节点 
    			}
    			else把次方大的接到结果链表 
    			{
    				然后该链表指针后移一个节点 
    			}
    		}
    		else if(q1遍历结束) 
    		{
    			就把q2的赋给temp
    		}
    		else  q2遍历结束 
    		{
    			就把q1的赋给temp
    		}
    	  每次循环结束前把temp接到结果链表 
    	}
    	p->next = NULL
    }
    

    (3) 多项式乘法
    用两个嵌套for把两个链表相乘,结果保存在temp,然后调用插入函数

    void EquationMultiply(EQU *const &head1, EQU *const &head2, EQU *&Multiplyresult)
    {
    	用new分配内存,具体细节不表  
    	声明EQU指针temp作为临时指针, p指针来代替Multiplyresult
    	声明EQU指针q1来代替head1,q2来代替head2
    	if (q1或者q2为空)
    	{
    		结束函数
    	}
    	for (如果q1遍历还没结束)
    	{
    		for (从q2头循环到q2尾)
    		{
    			把q1和q2相乘的结果保存到temp 
    			调用插入函数InterList(Multiplyresult, temp)
    		}
    	}
    
    }
    

    (4) 插入函数
    结果链表是按次方从大到小排序,用for循环找到插入点插入,有次方等于的就合并

    void InterList(EQU *&head,EQU *&temp)
    {
    	声明EQU指针q和p来代替被插入链表,p指在q的前一个节点 
    	for (通过q遍历链表即q不为空继续循环)
    	{
    		如果有次方相等就合并,没有就插入 
    	}
    }
    

    (5)输出函数
    遍历链表输出,链表为空等输出相应提示(相对简单,不详述)

    2.3.2代码截图






    2.3.3本题PTA提交列表说明。


    Q1:一开始没有合并同类项
    Q2:没有去除零项
    Q3:一开始没有用插入函数,导致代码复杂,小问题多,就写了插入函数

    3、阅读代码

    3.1题目

    给定一个链表,判断链表中是否有环。
    为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

    3.2解题思路

    通过使用具有 不同速度 的快、慢两个指针遍历链表,慢指针每次移动一步,而快指针每次移动两步 ,如果列表中不存在环,最终快指针将会最先到达尾部,此时我们可以返回 false,如果有环快指针就一定会追上慢指针。
    

    3.3代码截图

    3.3学习体会

    算法经典,时间复杂度o(n),空间复杂度o(1),我发现很多经典算法都是利用了两个或多个指针对链表操作,取得了可观的时间复杂度。
  • 相关阅读:
    WPF-WPF的内部世界-Binding
    WPF-XMAL-布局和控件-布局(一)
    SQL Server的简单使用
    redis的简单使用
    JWT
    C# 面试
    dapper的使用
    .NET发展史
    idea Jrebel升级后看不到且无法重新安装Jrebel
    laydate时间点击后马上消失
  • 原文地址:https://www.cnblogs.com/codedawn/p/10568257.html
Copyright © 2011-2022 走看看