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 一元多项式的乘法与加法运算

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

2.3.1设计思路(伪代码)

结构体定义blog

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.1题目

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

3.2解题思路

经过使用具备 不一样速度 的快、慢两个指针遍历链表,慢指针每次移动一步,而快指针每次移动两步 ,若是列表中不存在环,最终快指针将会最早到达尾部,此时咱们能够返回 false,若是有环快指针就必定会追上慢指针。

3.3代码截图

3.3学习体会

算法经典,时间复杂度o(n),空间复杂度o(1),我发现不少经典算法都是利用了两个或多个指针对链表操做,取得了可观的时间复杂度。
相关文章
相关标签/搜索