DS博客作业02--线性表

1.本周学习总结

1.1思维导图

DS博客作业02--线性表_第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代码截图

DS博客作业02--线性表_第2张图片

DS博客作业02--线性表_第3张图片
DS博客作业02--线性表_第4张图片
DS博客作业02--线性表_第5张图片
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代码截图

DS博客作业02--线性表_第6张图片

DS博客作业02--线性表_第7张图片
DS博客作业02--线性表_第8张图片

2.1.3本题PTA提交列表说明

DS博客作业02--线性表_第9张图片
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代码截图

DS博客作业02--线性表_第10张图片
DS博客作业02--线性表_第11张图片
DS博客作业02--线性表_第12张图片
DS博客作业02--线性表_第13张图片
DS博客作业02--线性表_第14张图片
DS博客作业02--线性表_第15张图片

2.3.3本题PTA提交列表说明。

DS博客作业02--线性表_第16张图片
Q1:一开始没有合并同类项
Q2:没有去除零项
Q3:一开始没有用插入函数,导致代码复杂,小问题多,就写了插入函数

3、阅读代码

3.1题目

给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
DS博客作业02--线性表_第17张图片

3.2解题思路

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

3.3代码截图

DS博客作业02--线性表_第18张图片

3.3学习体会

算法经典,时间复杂度o(n),空间复杂度o(1),我发现很多经典算法都是利用了两个或多个指针对链表操作,取得了可观的时间复杂度。

你可能感兴趣的:(DS博客作业02--线性表)