02-线性表
一、PTA实验作业
1.题目1:6-2 顺序表删除重复元素
2. 设计思路
typedef struct{
int data[maxsize];//数值
int length;//长度
}SqList;
typedef SqList *List;//用List替代*,方便后面代码书写
**主函数**
int i,n,a[maxsize],顺序表L,其中i为循环变量,n表示顺序表长度,数值a存放元素的值
输入n;
for i=0 to i=n-1
输入数值并存入数组a;
建立顺序表
删除重复元素
输出删除结束后顺序表
销毁顺序表
end for
**建立顺序表**
void CreateSqList(List &L,int a[],int n){
int i
创建头结点L
L->length=0;
if(n==0)return
否则
for i=0 to i=n-1
把数组中元素依次赋给顺序表中元素
顺序表长度加一
end for
**输出顺序表**
void DispSqList(List L){
int i;
如果顺序表长度不为0
for i=0 to i=L->length-2
输出顺序表元素的值
end for
}
**删除重复元素**
void DelSameNode(List &L){
int i,j,k,flag=0,flag用来判断是否找到重复值
for i=0 to i<L->length
for j=i+1 to j=L->length-1
如果L->data[i]等于L->data[j]) 即存在重复元素
flag=1;
跳出循环
end for
如果flag等于1
for k=j to k=L->length-1
从第j+1个元素开始后面的元素依次往前挪
flag=0,flag赋零,为下一次查找做准备
顺序表长度减一
i--为下一轮遍历做准备
end for
}
3.代码截图
4.PTA提交列表说明。
(1)错误1:删除结果错误
题中测试数据能过,但是当输入5 1 2 2 2 2时发现输出结果为1 2 2,删除不彻底?调试发现第三个元素,即第二次出现2后,才进入遍历查找重复元素,导致输出多出
一个2
(2)错误2:空表
换用flag判断来删除重复元素,并增加i--,即将循环开始位置前移一个,保证所有重复元素都被遍历到。但这次出现空表错误,输入测试数据0时,发现输出一串数字,在输出函数中控制顺序表长度大于0才输出,提交,答案正确!
1.题目2:6-4集合的基本运算
2. 设计思路
typedef struct LNode //定义单链表结点类型
{
ElemType data;
struct LNode *next;
} LinkList;
**主函数**
int main()
{
LinkList *ha,*hb,*hc;
ElemType a[100]={0};//数组初始化
ElemType b[100]={0};
int i=0;
char ch;
当输入的字符不是换行符时
将元素依次存入数组a
建立链表ha
同理 当输入的字符不是换行符时
将字符存入数组b
建立链表ha
输出链表ha,hb
对链表ha,hb中元素进行排序
输出排序后的链表ha,hb
建立新链hc
求ha,hb的并集,即ha,hb剔除多余重复元素后的全部元素,将这些元素存入hc
输出hc
求ha,hb的交集,即ha,hb中均存在的元素并将这些元素存入hc
输出hc
求ha,hb的差集,即ha,hb剔除所有重复元素后的全部元素并将这些元素存入hc
输出hc
销毁链ha,hb,hc
return 0;
}
***输出函数*
void DispList(LinkList *L){
LinkList *p;
p指向第一个节点
遍历链表,输出各节点元素
}
**构造函数**
void CreateListR(LinkList *&L,ElemType a[],int n){
LinkList *s,*r;
int i;
创建头结点L
r指向头结点
for i=0 to i=n-1
创建数据节点s
将数组a中元素依次赋给节点s
r->next=s
r=s
end for
r->next=NULL;//尾节点next域置为NULL
}
**销毁函数**
void DestroyList(LinkList *&L){
LinkList *pre=L,*p=L->next;//pre指向头结点,p指向第一个节点
当p!=NULL
释放pre节点
pre,p同步后移,指向下一个节点
循环结束后,释放尾结点
}
**排序函数**
void sort(LinkList *&L){
LinkList *p,*pre,*q;
p指向L第二个数据节点
L->next->next=NULL;//构造只喊一个数据节点的有序表
当p!=NULL
q保存p节点后继节点的指针
pre指向头结点
当pre->next!=NULL并且pre->next->data<p->data
pre指向下一个节点,找到要插入的位置
在pre后插入p
p=q//扫描余下节点
}
**求并集**
void Union(LinkList *ha,LinkList *hb,LinkList *&hc)
{
LinkList *s,*pa,*pb,*pc;
创建头结点hc;
pa指向链ha的第一个节点,pb指向链hb的第一个节点,pc指向hc的头结点
当pa!=NULL且pb!=NULL
如果pa->data<pb->data
创建数据节点s
s->data=pa->data;
pc->next=s
pc=s
pa=pa->next;
如果 pa->data>pb->data
创建数据节点s
s->data=pb->data;
pc->next=s
pc=s
pb=pb->next;
如果 pa->data=pb->data
创建数据节点s
s->data=pa->data;
pc->next=s;
pc=s;
pa=pa->next;
pb=pb->next;
循环结束后
当pb!=NULL,即hb链未遍历完
pa=pb;
当pa!=NULL
创建数据节点s
s->data=pa->data;
pc->next=s;
pc=s;
pa=pa->next;
pc->next=NULL; //尾节点next域置为NULL
}
**求交集**
void InterSect(LinkList *ha,LinkList *hb,LinkList *&hc)
{
LinkList *s,*pa,*pb,*pc;
创建头结点hc;
pa指向链ha的第一个节点,pb指向链hb的第一个节点,pc指向hc的头结点
当pa!=NULL
{
pb指向链hb的第一个节点
当pb!=NULL
{
如果pb->data=pa->data
创建数据节点s
s->data=pa->data;
pc->next=s;
pc=s;
}
pb=pb->next;
}
pa=pa->next;
}
pc->next=NULL; //尾节点next域置为NULL
}
**求差集**
void Subs(LinkList *ha,LinkList *hb,LinkList *&hc)
{
LinkList *pa,*pb,*pc,*s;
pa指向链ha的第一个节点
int flag=0; //flag用来判断是否有重复元素
创建头结点hc;
pc指向hc的头结点
当pa!=NULL
{
pb指向链hb的第一个节点
当pb!=NULL
{
如果pb->data==pa->data
flag=1,跳出循环
pb=pb->next;
}
如果flag==0
{
创建数据节点s
s->data=pa->data;
pc->next=s;
pc=s;
}
pa=pa->next;
flag=0;
}
pc->next=NULL; //尾节点next域置为NULL
}
3.代码截图
4.PTA提交列表说明。
(1)错误1:答案错误
一开始很奇怪三个函数输出的结果是一样的,修改好几次后面的函数,其余俩个函数不是输出不了就是输出一样。后来发现是没有申请数据节点,直接指向ha,hb的数据节点,求并集时链还可以连起来,后来再链新链时可能指针就乱了,通过申请新的数据节点,然后指向这个数据节点,进行交,并,差集运算,运行结果对了
(2)错误2:格式错误
仔细根据题目要求,修改了输出函数,答案正确
1.题目3:7-2 一元多项式的乘法与加法运算
2. 设计思路
typedef struct LNode //定义单链表结点类型
{
ElemType data;//系数
ElemType power;//次方
struct LNode *next;
} LinkList;
**主函数**
int main()
{
LinkList *ha,*hb,*hc;
创建链表ha,hb,hc
计算ha,hb中元素构成单项式的乘积,将结果存入链表hc
hc中元素的按次方递减排列
输出链表hc
计算ha,hb中元素构成单项式的乘积,将结果存入链表hc
hc中元素的按次方递减排列
输出链表hc
销毁链表ha,hb,hc
return 0;
}
**构造函数**
void CreateListR(LinkList *&L){
LinkList *s,*r;
int e1,e2,i,n;e1用来存放系数,e2用来存放次方,n表示元素个数
输入n
创建头结点L
r=L;
for i=0 to i=n-1
创建数据节点s
输入e1,e2
s->data=e1;
s->power=e2;
r->next=s;
r=s;
end for
r->next=NULL;//尾节点next域置为NULL
}
**销毁链表**
void DestroyList(LinkList *&L){
LinkList *pre,*p;
pre指向头结点,p指向第一个节点
当p!=NULL
释放pre节点
pre,p同步后移,指向下一个节点
循环结束后,释放尾结点
}
**输出链表hc**
void DispList(LinkList *L){
LinkList *p;
p指向第一个节点;
如果p==NULL
输出NULL
遍历链表,输出各项的系数和次方
如果系数为0 则不输出
如果结果是零多项式输出0 0
}
**加法函数**
void add(LinkList *ha,LinkList *hb,LinkList *&hc){
LinkList *pa,*pre,*pb,*s;
创建头结点hc
hc->next=NULL//链表初始化
pre指向hc头结点;
pa指向ha第一个节点;
pb指向hb第一个节点;
当pa!=NULL且pb!=NULL时
{
遍历ha,hb,如果有次方相同项则合并同类项,否则按次方由大到小连接:
如果pa->power<pb->power
创建数据节点s
s->data=pb->data;
s->power=pb->power;
pre->next=s;
pre=s;
pb指向下一个节点;
如果pa->power>pb->power
创建数据节点s
s->data=pa->data;
s->power=pa->power;
pre->next=s;
pre=s;
pa指向下一个节点;
如果pa->power=pb->power
创建数据节点s
s->data=pa->data+pb->data;
s->power=pa->power;
如果s->data==0 让s->power=0;
pre->next=s;
pre=s;
pa,pb均指向一个节点
}
如果pb还没有遍历完
pa=pb;
当 pa!=NULL
{
创建数据节点s
s->data=pa->data;
s->power=pa->power;
pre->next=s;
pre=s;
pa指向下一个节点
}
pre->next=NULL; //尾节点next域置为NULL
}
**乘法函数**
void multipy(LinkList *ha,LinkList *hb,LinkList *&hc){
LinkList *pa,*pre,*pb,*s;
创建头结点hc
hc->next=NULL//初始化
pre指向头结点hc;
pa指向ha第一个节点;
pb指向hb第一个节点;
当pa!=NULL
pb=hb->next;
当pb!=NULL
创建数据节点s
s->data=pa->data*pb->data;
s->power=pa->power+pb->power;
pre->next=s;
pre=s;
pb=pb->next;
pa=pa->next;
pre->next=NULL;//尾节点next域置为NULL
}
**排序函数**
void sort(LinkList *&hc){
LinkList *p,*pre,*q,*r;
p指向hc第二个数据节点
hc->next->next=NULL;//保证只有一个数据节点
r=hc;
当p!=NULL
q=p->next;
pre=hc;
当pre->next!=NULL且pre->next->power>p->power
交换俩个节点位置
pre=pre->next;
p->next=pre->next;
pre->next=p;
p=q
当r->next!=NULL
如果r->data=0
r->power=0;
如果相邻俩项次方一样,合并同类项
如果r->data=0,r->power=0;
r->next=r->next->next;
删除相邻俩项后者
r=r->next;
}
3.代码截图
4.PTA提交列表说明。
错误1:输入数据有0 0输出不对
在输出函数控制为0时不输出,以及零多项式输出0 0
错误2:
输入2 1 0 0 0 后发现程序崩溃,增加对输入时的合并同类项考虑,但是,依旧段错误。。。
2 0 0 1 0
二、截图本周题目集的PTA最后排名
1.顺序表PTA排名
2.链表PTA排名
3.我的总分:213
三、本周学习总结
1.谈谈你本周数据结构学习时间是如何安排,对自己安排满意么,若不满意,打算做什么改变?
这周空余时间,像没课的时候或者晚上都在完成PTA作业或者预习作业,PTA保证平均每天有一题正确的进度吧。目前觉得还是比较满意,一般到截止日期前题集已经基本上做的差不多了,不会很赶,每天适量代码,在学也不会太累,也不会太占用其他科目学习时间。遇到问题一般是先调试,自己解决不了,会去询问学长,一般最后才会选择借阅同学的代码,找差异
2.谈谈你对线性表的认识?
我对线性表的感觉就是,顺序表比链表好懂,但是各有各的好处,顺序表适合查找操作,链表适合插入删除操作,针对问题选择合适的表,效率会差很多
线性表总结
- 1.顺序表有关
(1)建表
(2)顺序表初始化
(3)销毁线性表
(4)按元素查找
(5)插入数据元素
(6)删除数据元素
(7)排序
(8)合并
(9)区间删除 - 2.链表有关
(1)插入,删除节点
(2)建立单链表(头插法,尾插法)
(3)初始化
(4)排序
(5)合并
(6)区间删除
(4)元素查找
3.代码Git提交记录截图
四、阅读代码
炳辉同学的一元多项式的乘法与加法运算
代码功能:实现一元多项式的乘法和加法计算
优点:
这题我和炳辉同学的思路差不多,都是实现加法,乘法,合并同类项,排序这几个功能,但是对于一些特殊情况我的代码不是运行奔溃就是结果错误,所以,我主要是学习他对于这些特殊值的考虑和处理
- 对于有系数为0的项,他利用if(p->data==0) continue;这种跳出循环继续下一轮循环,来实现系数为0无输出
- 用flag做标记,用if(flag==1) printf("0 0")来实现零多项式输出0 0