DS博客作业02--线性表
1.本周学习总结(0--2分)
1.1思维导图
1.2.谈谈你对线性表的认识及学习体会
经过一段时间学习线性表,我的理解称它是一种高阶的数组,在使用以及操作过程中要考虑它的头和尾,还有就是它的“小名”->>自定义的指针指向其首结点,在学习过程中觉得线性表的相关内容要好理解一些,到链表时指针域和指针之间的链接(比如开始的时候看头插和尾插法时候脑海里就就联想不了它们插入时的链接状态,粗暴的背下来叭,后面脱离书本能写出来)这块比较抽象,有的动手画画图还是能看懂的,但实际的操作这块还是不够熟练比如删除元素,有时大脑卡壳了一下指针指到哪里都乱了。在双链表这块只是简单的了解了一下,循环链表也是能理解的,但也没写程序操作过。有序表自认为是本章的理解较为困难的地方(比如二路归并那题就看了好一会......),其实思路也清晰,但是到实际的操作不看书本的话实现还是比较困难的。
2.PTA实验作业
6-4 顺序表操作集
- 本题要求实现顺序表的操作集。
2.1.1设计思路(伪代码)
- 设计思路:依照题目要求,建立空的线性表。
元素的查找:遍历线性表,寻找线性表中是否存在所查找元素,存在即返回该元素位置,否则即返回错误。
元素的插入:首先判断Maxsize 是否已满,如不满再判断插入位置是否合法,若合法即寻找对应的位置进行插入。
元素的删除:首先判断是否存在所要删除的数据,若存在即进行删除操作。
List MakeEmpty()//建立空顺序表
定义链表L;
给L申请动态内存空间
L->Last赋值为-1;//目的是Last每次指的就是最后一个数据,而不是下一个数据的下一个
返回L;
Position Find( List L, ElementType X )//找顺序表中X位置
定义i为作为循环变量也做返回的位置
for i=0 to L->Last do i++
if(线性表的值==所要查找元素的值)
end for
返回ERROR //若循环结束也没找到该元素的位置即返回
bool Insert( List L, ElementType X, Position P )//将整数X插入P位置
定义i;
判断空间是否已满,若满则返回false
在判断插入位置是否是合法的,否则返回false
for i=L->Last+1 to P do i--
将L->Data[i]向后移
endl for
将插入数赋值给Data[i]
长度增加
返回true
bool Delete( List L, Position P )//输出P位置的数据
定义i
判断P是否是合法位置,否则返回false
for i 为 p 的位置开始 to i<L->Last do i++
用P+1的位置数据将P位置覆盖掉,后面的数据一次赋给前一个
end for
L->Last--
返回 true
2.1.2代码截图
2.2.3代码提交列表及说明
- Q1:编译错误:开始用new 申请动态内存空间
- A1:改用malloc即可。
- Q2:部分错误。
- A2:经过反复查看代码发现一开始的L->Last赋值应是-1,保证Last 每次指最后一元素,而不是最后元素的下一个,依次修改相关Last的地方即可。
6-8 链表倒数第m个数
- 已知一个带有表头节点的单链表,查找链表中倒数第m个位置上的节点。
2.2.1设计思路(伪代码)
- 方法1设计思路:按照题目所给以尾插法建立链表,一开始抖机灵的转为数组来操作,将链表数据依次赋值给数组,记住总链表个数,再以总长减去m个数,即可得链表倒数m个数
创建p指向L的头结点
定义i,数组a[];定义总数数据total
while(p)
将p所指数据依次赋值给数组
i++计算链表元素总长度
将长度 total=i
判断 m是否小于总数total // 即判断位置是否合法
返回a[total-m] //总长减去m个数
否则返回-1
2.2.2代码截图
- 方法2设计思路:定义两个指针指向L,将其中一指针p2指向m之前,遍历继续循环p2个数,遍历p1p2.当P2指向链表尾时,循环结束时即返回此时P1指向的数据,否则返回-1。
定义 *p1,*p2,i
使p1,p2指向L->Last
for i=0 to m do i++
判断p2是否为NULL
p2=p2->next;
end for.
while(p2)
{
遍历p1,p2.
}
返回p1的数据
else -1.
代码截图
2.2.3代码提交列表及说明
- Q1:部分错误:其中有一个测试点没过,在运行是时发现是与m点的范围有关,但是一直没想到,于是找同学的代码看看。
- A1:我的代码没有判断m小于0 的情况,于是造成测试点的位置无效的错误一直没过,修正过来即可。
7-1 两个有序序列的中位数
- 题目: 已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,AN−1的中位数指A(N−1)/2的值,即第⌊(N+1)/2⌋个数(A0 为第1个数)。
3.3.1设计思路
- 方法1解题思路:按照题目要求尾插法建立链表A1,A2。合并两个链表(不去重复元素),再去除重复元素并计算新链表总长同时返回。
(主要函数伪代码)
合并链表函数:
设两个指针指向L1,L2头结点。
创建新的链表s
while(两条链)
if(依次比较两个链的元素大小(L1->data>L2->data))
{
把L1元素插入新链
}else
{ 把L2->data元素插入新链}
else
{相等时同样插入新链}
if(如果有一条链先遍历完,把剩余元素插入新链)
输出中位数的函数:
定义head=L,pro:用来循环链表
定义temp,count,result ,i//记录链表数据、去除重复元素的长度、中位数、输出
使用i增加。
temp记录data.
pro指向L头。
while(pro链){
L=pro->next;//
if(temp==L->data)
{
删除操作}
else
{
保留不重复的元素,count++}
for(i=0 to (count+1)/2 do i++)
{
result存储跳出循环前的数据,也就是中位数
}
输出result。
3.3.2代码截图
- 方法2解题思路:建立两个数组,通过下标的增加,依次移动两个数组,同时边比较数据大小。
全局变量定义两个数组a[],b[];
main()
{
输入两个数组元素
调用函数DealWith();
return 0;
}
DealWith()
{
定义i,数据的中位数(控制循环跳出)
定义ai=0,bi=0; //表示两个数组的下标
while(ai+bi<i-1) //元素的个数中间位的前一个
{
if(a[ai]>=b[bi])
b[]数据下一个;
else
{
a[]数据下一个}
}
return a[ai]>b[bi]?b[bi]:a[ai}; //比较此时a[],b[]的数据,返回比较小的一个。
提交列表及其说明
- Q1:多种错误。
- A1:一开始使用链表的做法,按照输入样例输入,但返回的是6,改了许久没改出结果,做到后面的时候脑壳就乱了,就查找百度,看了数组的做法,觉得代码很简洁,就试着用数组来做一下。
- Q2:编译错误。
- A2:现在我们在学链表,还是要用链表做的,找了同学的代码对比,原来是我的代码合并后没有考虑去重复元素,在原来的基础上加上删除重复元素操作即可。
阅读优秀的代码
3.1 题目
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
示例:
给定
1->2->3->4 你应该返回 2->1->4->3
3.2 解题思路
比如有个链表,1->2->3->4->5,我们要交换3和4节点,那么正确的执行就是,3的上一个节点pre,应该指向4,然后3执行4的下一个节点5,最后4执行5。执行过程如下:
第一步:得到链表A 1->2->4->5,3被挂起,当然是另一种形式存在,就是 3->4->5。
第二步:得到 3->5,也就是将 3->4->5的4去掉。
第三步:将4指向3,得到结果链表,1->2->4->3->5,交换完成。
3.3.1 代码截图1(C++)
3.3.2代码截图2(Java)
3.3.3代码截图(Python)
3.4 学习体会
- 在力扣上看到的这道题目,题目的思路比较简单的,又分别在网上寻找三种语言的解法(也不确定是不是对的,感觉三种解法都相差不大qaq)C++的与我们现在所学的知识点相通,所以看下来是OK的。JAVA在网上看了一些JAVA的基础知识点,比如修饰符。修饰符是表示该变量使用范围的权限修饰符,如题中public。三个语言比较下来解法思路是相同的,不同话就是Python的if 判断不用加()(原谅我只看到表面上的hhh),其他的就是换了个名字。体会就是三种语言都有异同地方,我们要多学其他语言以便用尽量简洁和尽量节省的实现所求功能。(浏览了一下JAVA的基础简绍的博客,觉得这篇写的比较好理解,详见https://blog.csdn.net/xmc281141947/article/details/54598720)