DS博客作业02--线性表

1.本周学习总结

1.1思维导图

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

对于线性表的操作过程有有多问题可以探究,在很多的题目里有的甚至会对操作的时间进行规定,这就非常考究算法的效率。根据不同的情况对排序方法或者是对链表或顺序表的选择,可以节省其运行时间。而算法又是比较有难度的一部分,对初次认识一种算法的人仍需时间去理解,可以说这就是人与计算机不可兼得的一方面。
对于链表的操作,时刻都要考虑指向非法区域的情况,这也是我经常不自觉要忽略的一点。

2.PTA实验作业

2.1题目1:

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

输入格式:

输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:

输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。

2.1.1设计思路

对于这道题目我尝试了两种解决方法:

数组法:

这种方法对时间和空间的消耗都是魔鬼,但是对程序员却是十分友好,这也是我一开始使用这种方法的原因。
简而言之,十分暴力。

!--以下伪代码都将采用python缩进表示语句块的方法--<

定义存储多项式的数组a[MAX],b[MAX]
以及用来存储的数组plus[MAX],Mult[MAX]
//对于所有数组都用静态,这样他们就都是0了,方便判断是否为空
//还有就是数组下标就代表有几次方,其内容就是系数
//下面开始对结果计算的操作:
//乘法:
for i = 0 to MAX-1:
    if a[i]:
        for j = 0 to MAX-1:
            if b[i]:
                Mult[i + j] += a[i] * b[j]  //系数相乘,指数相加
//加法
for i = 0 to MAX-1
    if a[i] or b[j]:
        plus[i] += (a[i] + b[i])

//如上便完成了操作过程

接下来是链表法:

//代码这东西,不是电脑难受,就是我难受(小声嘀咕)

//先丢出结构体
typedef struct LNode {
    int coe;
    int index;
    LNode * next;
}*LinkList;
//常规的建表输出表就不贴啦
//我先设计了两个初级函数,用于计算每一项的结果,并调用Insert函数插入结果链表中:
void Multply(LinkList L1, LinkList L2, LinkList result)
    LinkList p = L1, q
    while p->next://遍历
        初始化q为L2
        while q->next://遍历
            为elem分配空间,然后将p,q节点的计算结果存储到elem
            if elem->coe == 0:
                elem->index = 0
        p = p->next
void Add(LinkList L1, LinkList L2, LinkList result)
//Add函数也比较简单,把每个链表的节点丢给Insert函数就好啦
//这两个函数的大致功能类似,只不过是一个节点中转站

//接下来是Insert函数,其大致思想就是利用输入数据的指数递减的特点,尝试查找比elem指数小的节点
void Insert(LinkList elem, LinkList &result)
    while p->next:
        if p->next->index == elem->index://说明找到
            将elem的系数与当前p->next相加
            delete elem
            return; //return 很重要
        else if p->next->index < elem->index://找过头了还是没有找到
            将elem插入在当前p->next的前面
            return;
        p = p->next
    //经过上述循环仍没找到说明应该插在末尾  
    插在末尾

2.1.2代码截图

数组实现:

链表实现:


2.1.3本题PTA提交列表说明


WA1:忘记考虑系数为0时指数不为0的情况
Solution:在Insert之前加个if语句判断就好了

WA2:我以为题目的“0 0”情况是有系数为0的就用合并输出。。
Solution:去和之前写的数组法对比了一下差别,再回过头来看看题目才发现

2.2题目2:

已知两个递增链表序列L1与L2,2个链表都是带头结点链表。设计函数实现L1,L2的合并,合并的链表仍然递增有序,头结点为L1的头结点。 合并后需要去除重复元素。

    * 输入格式: 输入分两行,先输入数据项个数,再输入数据项,数字用空格间隔。
    * 输出格式: 在一行中输出合并后新的递增链表,数字间用空格分开,结尾不能有多余空格;

你需要实现的函数为:

void MergeList(LinkList &L1,LinkList L2);//合并链表

2.2.1设计思路

这题不算难,但是手上有一个有趣的解法就拿出来分享一下,其大致原理如图

实现思想:

void MergeList(LinkList &L1, LinkList L2)
    采取空间换时间的方法,新建一个结果链表L3
    head = L3
    while L1 or L2:
        if L1->data == head->data:
            L1=L1->next
        else if L2同上:
        else:
            使head->next指向L1, L2中的最小值节点
            并使该节点指向它的下一个
    head->next = NULL
    L1 = L3

2.2.2代码截图

2.2.3本题PTA提交列表说明

WA1:写这题时也不知怎么了,感觉脑子突然不在线了,出现很多低级错误,比如定义了结果链表L3,但是都没用过就给人家L1=L3,太智障了我。。
Solution:让脑子冷静一下。。。

WA2:发现有的重复数据还是没有过滤掉
Solution:设置断点调试,最后发现是只考虑了L1,L2有共同元素却没有考虑单个链表中重复的情况。

2.3题目3:

本题要求实现一个函数,将给定单向链表逆置,即表头置为表尾,表尾置为表头。链表为带头结点链表。请实现逆转函数。

输入说明:

第一个数输入单链表结点个数n,后面输入n个正整数。

输出说明:

输出逆转后的单链表内容,数和数之间空格隔开,尾部不能有空格。若链表为空,输出 空链表!

2.3.1设计思路

void ReverseList(LinkList &L)
    p = L->next;
    定义操作变量before = NULL,after
    while p:
        //移动after的位置
        after = p->next
        //先改变p的指向
        p->next
        移动before和p
    L->next = before

这个感觉实在是太抽象了,伪代码不太好表达,所以用PPT做了个动画,应该会比较好懂

元素解释:红色代表操作变量,黄色代表链表的每一个节点,蓝色代表指针指向

2.3.2代码截图

2.3.3本题PTA提交列表说明

WA1:可能是太累了,一直没给L头节点,然后输出函数也是写的没头节点,一直在纳闷。
Solution:经历太多失败恍然大悟

3.阅读代码

3.1 题目

3.2 解题思路

3.3 代码截图

3.4 学习体会

猜你喜欢

转载自www.cnblogs.com/Rasang/p/10583243.html