数据结构实验二

南昌航空大学实验报告

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.时间复杂度为On*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;

 }

 

posted @ 2022-03-14 23:15  安良  阅读(400)  评论(0编辑  收藏  举报