DS博客作业02--线性表
1.本周学习总结 ![](https://img2018.cnblogs.com/blog/1474783/201903/1474783-20190331003441079-1476739858.jpg)
1.1思维导图
1.2.谈谈你对线性表的认识及学习体会。
认识:线性表的学习相当于对于对上学期结构体数组和链表的一个复习和更深一步探究,在结构体数组为主的顺序表和以指针为主的链表都可以写出程序的时候,后者无疑更加灵活,在学习了C的基础上,数据结构要求的则是更加合适高效的算法。
学习体会:顺序表的学习较为轻松,大概是因为数组比较简单,容易掌握。相比之下,链表就比较麻烦了,指针一不小心没用好就容易出错,对于什么时候保存结点,什么时候直接使用结点有些模糊。在敲pta的时候,因为这次pta比较简单,开始的时候就是直接模仿书上的代码,照葫芦画瓢,后来发现什么都没吸收到。。。这种学习方法还是不对的,后面的题就感觉靠书是不够的,链表小白的学习是离不开画图滴,画出链表的结构会比较直观,慢慢掌握插入、删除这些基本算法。在学习线性表的同时,对于C++的基本编程也越来越熟悉,漫漫数构路,才刚刚开始,继续加油鸭!
2.PTA实验作业 ![](https://img2018.cnblogs.com/blog/1474783/201903/1474783-20190331003551768-968456273.jpg)
2.1.题目1——删除顺序表中重复元素:
设计一个算法,从顺序表中删除重复的元素,并使剩余元素间的相对次序保存不变。
- 输入格式: 第一行输入顺序表长度。 第二行输入顺序表数据元素。中间空格隔开。
- 输出格式:数据之间空格隔开,最后一项尾部不带空格。
- 输出删除重复元素后的顺序表。
2.1.1设计思路(伪代码)
#####设计思想
重构顺序表,利用哈希查找法,将顺序表中的元素作为哈希数组的下标,下标出现一次后对应的哈希元素加一,将元素值为1的存入新的顺序表
#####伪代码
#定义哈希数组
static int hash[maxsize]
#重构顺序表
- 保存顺序表长度
len=L->length
L->length=0;
- 哈希查找重复
for i=0 to len
hash[ L->data[i] ]++;
if hash[ L->data[i] ] == 1
存入新顺序表
end if
end for
- 记住顺序表新长度
2.1.2代码截图
只展示了主要函数代码
- 第一种——哈希查找
- 第二种——flag判断
2.1.3本题PTA提交列表说明
说明
1-3.最开始的做法是也是重构顺序表,采取类似冒泡法,通过遍历,比较元素是否相等,若相等即不存入,不存入的同时顺序表长度减一,这样写可以通过基本测试点,但对于特殊情况——全部重复数据,就会产生错误,L->length减到零,导致遍历的循环无法正常进行,这种方法不可行
4.采用最基本的方法——利用flag进行判断,若不重复立即写入,通过flag值变化判断是否重复,代码有点复杂,但是很容易通过;
5-6.上习题课的时候,老师讲了一种效率比较高的方法——哈希查找,即伪代码部分,代码更短了质量也更高了,方便了很多。
2.2 题目2——链表倒数第n个数
已知一个带有表头节点的单链表,查找链表中倒数第m个位置上的节点。
- 输入要求:先输入链表结点个数,再输入链表数据,再输入m表示倒数第m个位置。
- 输出要求,若能找到则输出相应位置,要是输入无效位置,则输出-1
2.2.1设计思路(伪代码)
#####设计思想
统计链表长度,将倒数的下标换算成正数的下标,输出对于的元素
#####伪代码
- 定义指针p指向L头节点
#特殊情况——找不到
if n <=0 || p==NULL || length-m<0
return -1
#统计链表长度
while p->next 不为空
length++;
p结点后移;
end while
- p指针回到L头节点,再次初始化!!!
#查找要找的结点
while i<length-m+1 && p不空
i++;
p结点后移;
return p->data
2.2.2代码截图
2.2.3本题PTA提交列表说明
说明:
1.在统计完链表长度后,忽略了p指针的再次初始化,导致查找结点出现错误;
2.在特殊情况的处理上出现了漏洞,没有判断length-n小于0的情况;
2.3—— 7-1.两个有序链表的中位数
已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0 ,A1 ,⋯,AN−1的中位数指A(N−1)/2的值,即第⌊(N+1)/2⌋个数(A0为第1个数)。
2.3.1设计思路(伪代码)
#####设计思想
将两条有序链表边排序边合并成一个新的有序表,根据中位数的下标输出中位数
#####伪代码
#创建L1、L2两条有序链表
void Create(LinkList &L,int n)
尾插法
#合并L1、L2
void MergeList(LinkList &L1,LinkList L2)
- 定义p1、p2分别指向L1、L2第一个元素,r始终指向L1的尾节点
- 逐一比较p1、p2元素大小,较小的插入新有序表中,直至有一条链扫描结束
while(p1不空&&p2不空)
if(p1->data >= p2->data)
s保存p2结点
s结点插入c中
p2、r结点后移
end if
else
r、p1结点后移
- 因为两条链等长
if p1空
p2剩余元素查到r后面
#在新有序表中查找中位数
while( i<=n && L1不为空)
i++;
L1=L1->next
#输出L1->data
#销毁链表
_老师上课时讲到 遍历同时控制到达中间位置时即可输出中位数,更加方便!!!_
2.3.2代码截图
2.3.3本题PTA提交列表说明
说明
这道题是为了找中位数,实际上是两条有序链表的合并,且保存重复的元素,类似于pta的那道两条有序链表合并,且本题不要求 去重复、两条链表等长,所以在Devc上调试了一些小错误就过了,虽然比较简单,但还是比较有成就感嘻嘻。
之所以还是把这道题放上来,是因为感觉自己对于排序时链表结点操作还是不是很熟悉,所以写一下思路和伪代码,记录一下