数据结构实验二
南昌航空大学实验报告
二0 21 年 4 月 29 日
课程名称: 数据结构实验 实验名称: 线性表的链式存储结构
班级: 姓名: 同组人:
指导教师评定: 签名:
一、 需求分析
题目:一元稀疏多项式计算器
(1)设Pn(x)和Qm(x)分别为两个一元稀疏多项式,利用单链表存储Pn(x)和Qm(x).
(2)从键盘输入一元多项式的信息,建立一元稀疏多项式Pn(x)和Qm(x),并输出。
(3)实现Pn(x)和Qm(x)相加,并输出两者的和Pn(x)+Qm(x).
(4)实现Pn(x)和Qm(x)相减,输出两者的差Pn(x)-Qm(x)。
就地逆置两者的差Pn(x)-Qm(x)。
1、在本次实验中,首先,从键盘输入两个多项式并建立多项式Pn(x)和Qm(x)的信息,然后使两个多项式相加,接着使输入的原始多项式Pn(x)和Qm(x)相减,最后逆置差,根据要求输出运算结果。
2. 演示程序以用户和计算机对话的方式进行,即在计算机终端上显示“提示信息”之后,由用户在键盘上先后输入两个多项式信息。输出多项式运算的结果。
3. 程序执行的命令包括:
(1) 输入多项式Pn(x);
(2) 输入多项式Qm(x);
(3) 将多项式Pn(x)和Qm(x)进行加法运算,输出运算结果;
(4) 将多项式Pn(x)和Qm(x)进行减法运算,输出运算结果;
(5) 将多项式Pn(x)和Qm(x)的差逆置,输出结果;
(6) 结束。
4. 测试数据
输入:
请输入P项数:
2
1 2
-1 3
请输入Q项数:
3
1 1
-1 2
3 3
Pn(x)+Qm(x)=x+2x^3
Pn(x)-Qm(x)=-x+2x^2-4x^3
逆置后的Pn(x)-Qm(x)=-4x^3+2x^2-x
选做题目:以单向链表解决约瑟夫环问题。
1.实验只需输入人数,密码与初始上限选择随机生成。
2.程序执行命令包括:CreateList(List &L);链表的创建
SortList(List &L,int len);链表的整合与输出
3.测试数据:输入人数:5
二、 概要设计
1. 抽象数据类型定义
为实现上述程序功能,需要一个抽象数据类型:图。
ADT Graph{
基本操作:
CreatePolyn(&head,int m);
操作结果:建立表示一元多项式的有序表
DestroyPolyn(&p)
操作结果:销毁一元多项式
PrintPolyn(&P)
操作结果:返回一元多项式的项数
AddPolyn(&pa,&pb)
操作结果:完成多项式加法运算
SubtractPolyn(&pa,&pb)
操作结果:完成多项式相减运算
2.程序模块
(1)主程序流程
void main{
初始化;
创建两个多项式,根据提示输入多项式信息;
两个多项式相加;
两个多项式相减;
逆置两个多项式之差;
}
(2)多项式相加;
(3)多项式相减;
(4)逆置多项式之差;
3.程序结构图
各模块之间的调用关系如图所示。
图1 模块之间调用关系图
选做:1. 抽象数据类型定义
为实现上述程序功能,需要一个抽象数据类型:图。
ADT Graph{
基本操作:
CreateList(&head,int m);
操作结果:返回总人数m
SortList(&p)
操作结果:按要求输出序号以及密码
InitList(&L)
操作结果:链表初始化
2.程序模块:
Void main()
{创建链表,
链表初始化,
生成链表,
输出
}
3.程序结构图:
三、 详细设计
1.数据类型及结构体
typedef struct PolyNode
{
int coef;//系数
int expn;//指数
struct PolyNode *next;
}PolyNode,*PolyList;
PolyList CreatPolyn(PolyList L,int m);//多项式创建
PolyList PrintPolyn(PolyList L);//多项式输出
PolyList Unite(PolyList L,int a,int b);//多项式重新生成
PolyList AddPolyn(PolyList L1,PolyList L2);//多项式相加
PolyList SubtractPolyn(PolyList L1,PolyList L2);//多项式相减
PolyList ReversePolyn (PolyList L);//多项式逆置
2.主函数
int main()
{
PolyList P,Q,L;
int m;
printf("请输入P项数:\n");
scanf("%d",&m);
if(m<=0)
{
printf("多项式p创建失败");
exit(0);
}
P=CreatPolyn(P,m);
printf("请输入Q项数:\n");
scanf("%d",&m);
if(m<=0)
{
printf("多项式Q创建失败");
exit(0);
}
Q=CreatPolyn(Q,m);
printf("P(x)+Q(x)=");
PrintPolyn(AddPolyn(P,Q));
printf("P(x)-Q(x)=");
L=SubtractPolyn(P,Q);
PrintPolyn(L);
printf("逆置后的P(x)-Q(x)=");
PrintPolyn(ReversePolyn(L));
}
选做:1.数据类型及结构体
typedef struct node
{
struct node *next;
int data1;
int data2;
} *List;
void InitList(List &L);链表初始化
CreateList(List &L);链表创建
SortList(List &L,int len);链表整合与输出
2.主函数
int main()
{
List L;
InitList(L);
int len=CreateList(L);
SortList(L,len);
return 0;
}
四、 调试分析
1. 调试过程中发现有段代码重复使用,拎出来作为子函数进行调用,简化了代码具体代码如下:
PolyList Unite(PolyList L,int a,int b)
{
PolyList L1;
L1=(PolyList)malloc(sizeof(PolyList));
L->next=L1;
L1->next=NULL;
L1->coef=a;
L1->expn=b;
return L1;
}
2.最开始运行发现运行时无法输出多项式相减的结果,总是输出空白,经检查发现是链表链接问题没处理好,当多项式P(或Q)全处理完后剩余的多项式Q(或P)并未链接到新的链表尾端,更改后的代码如下: while(p1)
{
p3=Unite(p3,p1->coef,p1->expn);
p1=p1->next;
}
while(p2)
{
p3=Unite(p3,-p2->coef,p2->expn);
p2=p2->next;
}
3.该算法经分析可知不论其加减法时间复杂度都为O(n^2),而逆置的过程时间复杂度为O(n)
选做:
1.第一次SortList函数里输出的同时忘记将它删除,更改后代码:List l=L;
List p=L;
for(i=len;i>=1;i--)
{
for(j=1;j<=m;j++)
{
if(l->next==NULL)
{
l=L->next;
p=L;
}
else{
if(j!=1)
p=p->next;
l=l->next;
}
}
printf("编号为%d密码为%d ",l->data2,l->data1);
m=l->data1;
List L1;
L1=l;
if(l->next==NULL)
{
p->next=NULL;
p=L;
l=L;
}
else{
p->next=L1->next;
l=p;
}
}
2.时间复杂度为O(n*n)
五、 用户手册
1. 本程序的运行环境为DOS操作系统,执行文件为:main.exe。
2. 进入演示程序后即显示文本方式的用户界面。
3. 程序运行后,按照提示信息输入两个多项式的信息。
4. 输出结果分别为两个多项式相加、相减、以及逆置差的结果。
六、 测试结果
输入:
请输入P项数:
2
1 2
-1 3
请输入Q项数:
3
1 1
-1 2
3 3
Pn(x)+Qm(x)=x^1+2x^3
Pn(x)-Qm(x)=-x^1+2x^2-4x^3
逆置后的Pn(x)-Qm(x)=-4x^3+2x^2-x^1
选做测试:
七、 附录
源代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct PolyNode
{
int coef;//系数
int expn;//指数
struct PolyNode *next;
}PolyNode,*PolyList;
PolyList CreatPolyn(PolyList L,int m)
{
L=(PolyList)malloc(sizeof(struct PolyNode));
L->next=NULL;
PolyList p,r;
p=L;
int i=1;
int j=-1;
while(i<=m)
{ int a,b;
scanf("%d %d",&a,&b);
if(a!=0)
{
r=(PolyList)malloc(sizeof(PolyList));
r->next=NULL;
p->next=r;
r->coef=a;
r->expn=b;
if(b<=j)
{
printf("请按指数递增方式输入");
exit(0);
}
j=b;
p=r;
}
i++;
}
return L;
}
PolyList PrintPolyn(PolyList L)
{
PolyList p;
p=L->next;
if(p==NULL)
{
printf("0\n");
return 0;
}
else{
if(p->coef==1)
printf("x^%d",p->expn);
else {
if(p->coef==-1)
printf("-x^%d",p->expn);else
printf("%dx^%d",p->coef,p->expn);
}
}
p=p->next;
while(p)
{
if(p->coef>0)
{
if(p->coef==1)
printf("+x^%d",p->expn);
else
printf("+%dx^%d",p->coef,p->expn);
}
else{
if(p->coef==-1)
printf("-x^%d",p->expn);
else
printf("%dx^%d",p->coef,p->expn);
}
p=p->next;
}
printf("\n");
}
PolyList Unite(PolyList L,int a,int b)
{
PolyList L1;
L1=(PolyList)malloc(sizeof(PolyList));
L->next=L1;
L1->next=NULL;
L1->coef=a;
L1->expn=b;
return L1;
}
PolyList AddPolyn(PolyList L1,PolyList L2)
{
PolyList p1,p2,p3,L3,temp;
L3=(PolyList)malloc(sizeof(PolyList));
L3->next=NULL;
p3=L3;
p1=L1->next;
p2=L2->next;
int a;
while(p1&&p2)
{
if(p1->expn<p2->expn)
{
p3=Unite(p3,p1->coef,p1->expn);
p1=p1->next;
}else
{
if(p1->expn==p2->expn)
{
a=p1->coef+p2->coef;
if(a!=0)
{
p3=Unite(p3,a,p1->expn);
}
p1=p1->next;
p2=p2->next;
}else
if(p1->expn>p2->expn)
{
p3=Unite(p3,p2->coef,p2->expn);
p2=p2->next;
}
}
}
while(p1)
{
p3=Unite(p3,p1->coef,p1->expn);
p1=p1->next;
}
while(p2)
{
p3=Unite(p3,p2->coef,p2->expn);
p2=p2->next;
}
return L3;
}
PolyList SubtractPolyn(PolyList L1,PolyList L2)
{
PolyList p1,p2,p3,L4,temp;
L4=(PolyList)malloc(sizeof(PolyList));
L4->next=NULL;
p3=L4;
p1=L1->next;
p2=L2->next;
int a;
while(p1&&p2)
{
if(p1->expn<p2->expn)
{
p3=Unite(p3,p1->coef,p1->expn);
p1=p1->next;
}else
{
if(p1->expn==p2->expn)
{
a=p1->coef-p2->coef;
if(a!=0)
{
p3=Unite(p3,a,p1->expn);
}
p1=p1->next;
p2=p2->next;
}else
if(p1->expn>p2->expn)
{
p3=Unite(p3,-p2->coef,p2->expn);
p2=p2->next;
}
}
}
while(p1)
{
p3=Unite(p3,p1->coef,p1->expn);
p1=p1->next;
}
while(p2)
{
p3=Unite(p3,-p2->coef,p2->expn);
p2=p2->next;
}
return L4;
}
PolyList ReversePolyn (PolyList L)
{
PolyList p,q,r;
p=L;
q=p->next;
if(q==NULL)
return L;
p->next=NULL;
while(q){
r=q->next;
q->next=p->next;
p->next=q;
q=r;
}
return L;
}
int main()
{
PolyList P,Q,L;
int m;
printf("请输入P项数:\n");
scanf("%d",&m);
if(m<=0)
{
printf("多项式p创建失败");
exit(0);
}
P=CreatPolyn(P,m);
printf("请输入Q项数:\n");
scanf("%d",&m);
if(m<=0)
{
printf("多项式Q创建失败");
exit(0);
}
Q=CreatPolyn(Q,m);
printf("P(x)+Q(x)=");
PrintPolyn(AddPolyn(P,Q));
printf("P(x)-Q(x)=");
L=SubtractPolyn(P,Q);
PrintPolyn(L);
printf("逆置后的P(x)-Q(x)=");
PrintPolyn(ReversePolyn(L));
}
选做代码:#include<stdio.h>
#include<stdlib.h>
#define M 1000
typedef struct node
{
struct node *next;
int data1;
int data2;
} *List;
void InitList(List &L)
{
L=(List)malloc(sizeof(List));
L->next=NULL;
}
int CreateList(List &L)
{
int i,j;
List l=L;
printf("输入人数:\n");
scanf("%d",&i);
printf("输出各个编号的密码:\n");
for(j=0;j<i;j++)
{ List p=(List)malloc(sizeof(List));
l->next=p;
p->next=NULL;
p->data1=rand()%i+1;
p->data2=j+1;
printf("编号为%d密码为%d ",p->data2,p->data1);
l=p;
}
printf("\n");
return i;
}
void SortList(List &L,int len)
{
int i,j,m,k=0;
m=rand()%len+1;
printf("初始报数上限为%d\n",m);
printf("输出顺序以及它们的密码为:\n");
List l=L;
List p=L;
for(i=len;i>=1;i--)
{
for(j=1;j<=m;j++)
{
if(l->next==NULL)
{
l=L->next;
p=L;
}
else{
if(j!=1)
p=p->next;
l=l->next;
}
}
printf("编号为%d密码为%d ",l->data2,l->data1);
m=l->data1;
List L1;
L1=l;
if(l->next==NULL)
{
p->next=NULL;
p=L;
l=L;
}
else{
p->next=L1->next;
l=p;
}
}
printf("\n");
}
int main()
{
List L;
InitList(L);
int len=CreateList(L);
SortList(L,len);
return 0;
}