DS博客作业02-线性表
1.本周学习总结
1.1思维导图
1.2.对线性表的认识及学习体会
线性表的学习让我最大的感受就是听得懂,看得懂,不会用。pta打起来是很困难,如果没有书本上的代码参考,很难完成一些稍微难点的,就是简单的头插法,尾插法是能够熟悉的运用,我觉得最大的困难是难以衔接上,时不时就出现野指针,箭头一不注意就不知道指向那里去了,我觉得这一章的学习确实不是很好理解,在做题目的时候一定要准备草稿纸,画画链的变化形式,不然很容易错误,很多时候画链帮忙理解,会容易很多。而且在练习pta的时候,要注重一些基础代码的套用,很多方法换汤不换药,可以背背代码。
2.PTA实验作业
2.1.题目1:题目名称
6-1 jmu-ds-区间删除数据
2.1.1设计思路(伪代码)
void CreateList(SqList &L,int n)
{
定义 i
L分配内存
存储length=n
for i to n
cin data//读取数据
end for
}
void DelNode(SqList &L,int min,int max)
{
定义循环变量 i j 区间端点kmin jmax 中间转换变量temp 重构线性表下标m
for i =1 to length //冒泡法排序
for j =0 to length
if data[j] >data[j+1] then
temp=data[j];
data[j]=data[j+1];
data[j+1]=temp;
end for
end for
for i=0 to length//遍历寻找区间
if data[i]==min then kmin=i;//寻找左区间,刚刚好区间和元素相等,记住元素下标
or data[i]<min then kmin=i+1;//区间比元素大,下标要加1
end for
for i=0 to length
if data[i]<=max then jmax=i;//寻找右区间,记住元素下标
end for
for i=0 to length //重构顺序表
if i<kmin||i>jmax) then L->data[m]=L->data[i];m++;//下标满足区间,存入顺序表
end for
L->length=m;//记录新顺序表长度
}
2.1.2代码截图
2.1.3本题PTA提交列表说明。
Q1:一开始以为题目的意思是不需要排序的,直接删除区间的里面的元素就行,
A1:发现按这个意思打出来提交没分,所以加了冒泡排序。先把无序的顺序表变成有序表在去处理
Q2:冒泡排序完后,又以为是区间都是顺序表找得到的,结果按这个思路,只能得一半分
A2:添加了区间不属于顺序表里面元素的情况
Q3:在寻找不属于顺序表元素的区间坐标是,找左区间的时候找到就记录,还是没有得满分,因为左区间在等与不等的情况下区间下标会有差别。
A3:把左区间分了2种情况,相等的时候直接记录,不等的时候要下标往前加一
2.2.题目2:题目名称
6-8 jmu-ds-链表倒数第m个数
2.2.1设计思路(伪代码)
int Find(LinkList L, int m )
{
定义 p,x 结点分别指向L链首结点
定义 i j 运算下标,作循环值
for i =0 to p!=NULL//统计链表的结点数,记录长度i
p=p->next;//结点后移
end for
j=i-m;//总长度减m为首结点到需要查找的结点循环次数
if m<=0||m>I then return -1 //不合法判断
or for j to 0 //循环遍历
x=x->next;
end for
return x->data;//返回结果
}
2.2.2代码截图
2.2.3本题PTA提交列表说明。
Q1:一开始没有判断不合法的情况没有返回-1,直接cout 数据
A1:改用return 加了一句if语句不合法就return -1;
2.3.题目3:题目名称
6-10 jmu-ds-有序链表的插入删除
2.3.1设计思路(伪代码)
void ListInsert(LinkList &L,ElemType e)
{
定义前驱结点pre,目标结点p,数据结点s
s分配动态内存
p结点指向链,且为首节点
while p //遍历链表,寻找插入位置结点
if data>=e //有序表寻找大于e的结点位置,跳出
pre=p;记住找到位置的前一个结点,就是要插入的位置
p ->next //结点后移
end while
s=e;//数据结点赋值
s->next=pre->next;//头插法把s节点插入pre后面,连接起来
pre->next=s;
}
void ListDelete(LinkList &L,ElemType e)
{
if L->next=NULL then return //空链结束
定义开关变量flag=0;
定义 目标结点p,前驱结点pre,删除中间变量结点d;
p指向L头结点
while p
if p.data=e then//寻找到了要删元素
flag=1;break;
pre=p;记住找到位置的前一个结点,就是要插入的位置
p ->next //结点后移
d=pre->next; //d结点存储
pre->next=d->next;//关系重建
delete (d);//释放结点
}
2.3.2代码截图
2.3.3本题PTA提交列表说明。
Q1:出现多次提交为0分的问题,查找了很多遍代码,没有解决。
A1:请求同学帮忙,原来是在建链的时候头节点没有给置域为NULL,但是后面函数用的时候也直接结点相等,导致链不能连接起来。更改添加置域,后成功。
Q2:还有一个问题,删除后链表为空,输不出来。
A2:开头加了一句if判断空链。结果可以输出。
3、阅读代码
3.1 题目
查找单链表的中间节点,要求只能遍历一次;
查找单链表的指定节点,我们可以通过不断遍历的到,但是题目要求只能遍历一次,那么我们原来的方法就不行了,这样我们就需要寻找新的途径。要解决这个问题,就需要应用快慢指针问题。
3.2 解题思路
定义两个指针,他们是fast和slow,开始他们都指向头节点,然后让他们同时遍历,但是每次fast走两步,即fast=fast->next->next,让slow走一步,即slow=slow->next,然后当fast走到最后的时候,slow所指的节点就是中间节点,这样我们就实现了遍历一次查找单链表的中间节点。
3.3 代码截图
3.4 学习体会
这个快慢指针我是在一年的天梯赛题集看到的。它是一种算法,这种算法对代码运行的要求非常高,可以处理很多要求只能遍历一次的问题,比如这个题目就是对这种算法的完美解释。两个指针搭配,可谓干活不累,我学习完这种方法后,想起来这次pta里面的一道题目,查找单链表倒数第k个节点。似乎也可以用快慢指针来解决了,fast指针先走k步,slow在开始走,fast指针走完,slow指针所指的就是倒数k个结点,这样又一次就可以把题目解决,今后处理这种问题,我要考虑用到这种方法,会简便很多。