实验报告2-多项式加法的链表设计与实现
- 格式:doc
- 大小:158.00 KB
- 文档页数:4
链表及其多项式相加一、实验目的1.了解线性表的链式存储结构,熟练掌握链表。
2.了解作为链表的多项式存贮方式。
3.熟悉掌握多项式加法的算法。
#include<stdio.h>#include <malloc.h>typedef struct linkline{int coef;int exp;struct linkline *next;}line;line *creat(){ /*建立多项式列表*/int n;line *head;line *p1,*p2;n=0;printf("(输入的数必须是整数,指数须从小到大依次输入,系数为零表示多项式结束)\n");p1=p2=(line *)malloc(sizeof(line)); /*开辟一个新单元*/scanf("%d%d",&p1->coef,&p1->exp); /*录入多项式*/if (p1->coef==0) head=0;else{while(p1->coef!=0){n++;if (n==1) head=p1;else p2->next=p1;p2=p1;p1=(line *)malloc(sizeof(line));scanf("%d%d",&p1->coef,&p1->exp);}p2->next=0;}return(head);}/* 以下是输出多项式的函数*/void print(line *p){line *p0;p0=p;printf(" ");do{printf("%dx的%d次幂",p0->coef,p0->exp);p0=p0->next;if(p0!=0) printf("+");}while(p0!=0);else printf(" 空多项式!!");printf("\n");}int compare(int m,int n) /*比较两个整数的大小的函数*/ {int j;if (m<n) j=-1;if (m==n) j=0;if (m>n) j=1;return(j);}void freeNode(line *w1) /* 释放一个表中的所有结点*/ {line *w2;w2=w1->next;while(w1){free(w1);w1=w2;w2=w2->next;}}line *AddLine(line *ha,line *hb) /*两个非空多项式相加*/ {line *la,*lb,*lc;int a,b,sum;lc=ha;la=ha;lb=hb;if ((ha==0)&&(hb!=0)) return(hb);while ((la!=0)&&(lb!=0)){a=la->exp; b=lb->exp;switch( compare(a,b) ) /*比较当前结点指数的大小*/ {{ ha=la; /*只修改la的指针*/la=la->next;break;}case 0:{ sum=la->coef+lb->coef;if(sum!=0){ /* 将其不为零的系数和保存*/la->coef=sum;ha=la; la=la->next;} /* end if*/else{ /* 分别删除系数和为零的对应的两个结点*/if (lc==la) {lc=lc->next;ha=lc;la=ha;} /* 刚开始时特殊处理头结点*/ else{ha->next=la->next;la=ha->next;}} /*end else*/hb=lb;lb=lb->next;break;}case 1:{ /* 将指数小的项插入到la的前部*/hb=lb->next;if(ha==la) {lc=lb;lb->next=ha;la=la->next; }else{ha->next=lb;lb->next=la;ha=la;la=la->next;}lb=hb->next;break;}} /*end swtich*/} /*end while*/if (lb!=0) ha->next=lb;return(lc);} /*end AddLine *//*************以下为主程序**************/main(){line *la,*lb,*lc;printf("请输入多项式La: ");la=creat();printf("请输入多项式Lb: ");lb=creat();printf("多项式La:\n");print(la);printf("多项式Lb:\n");print(lb);printf("多项式La与Lb的和是: \n");lc=AddLine(la,lb);print(lc);freeNode(lb);}二、实验原理顺序存储的线性表有一些弱点,其一,插入与删除元素需要大量移动元素;其二,预先分配存储空间时必须按最大的空间来分配。
题目:多项式加法多项式加法一、课题概述线性表是一种最简单、最基本,也是最常用的数据结构,其用途十分广泛,例如,用带表头结点的单链表求解一元整系数多项式加法和乘法运算。
现给两个一元整系数多项式,请求解两者之和。
输入两组数据,每一组代表一个一元整系数多项式,有多行组成,其中每一行给出多项式每一项的系数和指数,这些行按指数递减次序排序,每一组结束行为0 -1。
输出三组数据,前两组为一元整系数多项式,最后一组为两个多项式的和。
一元整系数多项式输出形式如下:(1)多项式项4x输出为4X(2)多项式项4x2输出为4X^2(3)第一项系数为正数时,加号不要输出(4)除常系数项外,项系数为1不显式输出,-1输出为-例如,4x3- x2+x-1正确输出形式为4X^3-X^2+X-1,错误输出形式为+4X^3-1X^2+1X-1二、设计与实现1、类的层次关系及核心算法分析:项节点类Trem中定义了三个私有变量,系数coef、指数exp和指向下一个项节点的指针域link。
多项式类Polynominal被声明成项节点类Trem类的友元类。
公有函数InsertAfter构造一个新的项节点,其系数为c指数为e,并将新节点插入在调用该函数的项节点及后继节点之间。
多项式类Polynominal中包含了3个公有成员函数:AddTerms,Output和PolyAdd。
AddTerms函数通过输入流in,输入多项式的各项构造一个多项式的单循环链表;Output函数将多项式按降幂方式送输出流;PolyAdd函数实现将多项式r加到指针this指示的多项式上。
AddTerms函数从输入流in按降幂输入各项(c,e)来构造多项式的单循环链表,当输入(0,-1)是构造过程结束。
Output函数遍历单循环链表将多项式按降幂方式送输出流,它调用项类Trem 上重载的“<<”操作符实现按项输出。
多项式加法,设有多项式p(x)和q(x),分别用单循环链表表示。
两个多项式相加实验报告主要实验内容:根据所学的数据结构中线性结构(线性表)的逻辑特性和物理特性及相关算法,应用于求解一个具体的实际问题----------两个多项式相加一、运行环境:visual C++二、需求分析(1)掌握线性结构的逻辑特性和物理特性(2)掌握线性结构的各种相关算法(3)掌握将算法转换成程序的方法和步骤(4)掌握采用线性结构解决实际问题。
三、概要设计1、抽象数据类型一元多项式的定义如下:ADT Polynomial { 数据对象:D={ a i | a i∈TermSet, i=1,2,...,m, m≥0TermSet 中的每个元素包含一个表示系数的实数和表示指数的整数 }数据关系:R1={ <a i-1 ,a i >|a i-1 ,a i∈D, i=2,...,n,且a i-1中的指数值<a i中的指数值}基本操作:CreatPolyn ( &P, m )操作结果:输入 m 项的系数和指数,建立一元多项式 P。
DestroyPolyn ( &P )初始条件:一元多项式 P 已存在。
操作结果:销毁一元多项式 P。
PrintPolyn ( &P )初始条件:一元多项式 P 已存在。
操作结果:打印输出一元多项式 P。
PolynLength( P )初始条件:一元多项式 P 已存在。
操作结果:返回一元多项式 P 中的项数。
AddPolyn ( &Pa, &Pb )初始条件:一元多项式 Pa 和 Pb 已存在。
操作结果:完成多项式相加运算,即:Pa = Pa+Pb,并销毁一元多项式 Pb。
SubtractPolyn ( &Pa, &Pb )… …} ADT Polynomial2、一元多项式的实现:typedef OrderedLinkList polynomial;// 用带表头结点的有序链表表示多项式结点的数据元素类型定义为:typedef struct { // 项的表示float coef; // 系数int expn; // 指数 term, ElemType;四、详细设计线性表的应用--多项式相加问题多项式的相加操作是线性表处理的典型例子。
实验一:两个多项式相加相乘链表实现学生姓名:#班级:@12学号:完成时间:2015.06.25本人郑重声明:本实验的程序代码编写与调试、实验报告的撰写均由本人独立完成,如被发现抄袭或与其他同学作业雷同,同意取消该实验成绩!声明人:#2015.06.25【实验内容】I.设计构造两个链式线性表,用来表示两个一元多项式II.程序允许用户手工输入这两个线性表,每个线性表中的每个数据元素包含两个值,系数Pi和幂qi;输入方式自定;III.程序对两个多项式进行相加,然后输出一个相加后的一元多项式。
IV.两个多项式相乘(选做)。
【编程思路】1.创建链表:先分别输入两个多项式的项数以及调用Createlist()函数按降幂顺序输入各项的系数和次数,构建出两个多项式的链表。
两个多项式的系数和次数同样按降幂顺序存入两个线性表a、b中,头结点分别为head_a,head_b。
2.多项式相加:创建一个新链表,作为相加后所得结果的多项式的链表寄存处。
定义两个临时链表节点指针pa和pb,分别指向两个链表头结点的下一位(注:链表的头结点不存项)。
通过比较两个多项式的首项确定最高次幂,用max_qi记录。
然后用一个for循环从两个链表中寻找,判断pa和pb当前位置有无次数为i(i为循环变量)的项,有则合并同类项。
如果pa、pb次数等于i,两对应系数相加,和其系数一起存入新节点中,再将新节点插入新链表中,pa、pb随后后移一个单位;如果pa的次数小于i,pb次数等于i,则只加pb项,也存入新节点并插入新链表中,随后pb向后移动一个单位;如果pb的次数小于i,pa次数等于i,处理方法与上一种情况类似。
如果pa和pb次数均小于i,则i减小1,进入下一次循环,再作比较。
若pa或pb为空,则将不为空的多项式链表的剩余项逐一赋给新链表即可。
3.多项式相乘:创建一个新链表,作为相乘后所得结果的多项式的链表寄存处。
定义两个临时链表节点指针pa和pb,分别指向两个链表头结点的下一位。
实验二链表操作实现实验日期:2017 年 3 月16 日实验目的及要求1. 熟练掌握线性表的基本操作在链式存储上的实现;2. 以线性表的各种操作(建立、插入、删除、遍历等)的实现为重点;3. 掌握线性表的链式存储结构的定义和基本操作的实现;4. 通过本实验加深对C语言的使用(特别是函数的参数调用、指针类型的应用)。
实验内容已知程序文件linklist.cpp已给出学生身高信息链表的类型定义和基本运算函数定义。
(1)链表类型定义typedef struct {int xh; /*学号*/float sg; /*身高*/int sex; /*性别,0为男生,1为女生*/} datatype;typedef struct node{datatype data; /*数据域*/struct node *next; /*指针域*/} LinkNode, *LinkList;(2)带头结点的单链表的基本运算函数原型LinkList initList();/*置一个空表(带头结点)*/void createList_1(LinkList head);/*创建单链表*/void createList_2(LinkList head);/* 创建单链表*/void sort_xh(LinkList head);/*单链表排序*/void reverse(LinkList head);/*对单链表进行结点倒置*/void Error(char *s);/*自定义错误处理函数*/void pntList(LinkList head);/*打印单链表*/void save(LinkList head,char strname[]);/*保存单链表到文件*/任务一创建程序文件linklist.cpp,其代码如下所示,理解LinkList类型和基本运算函数后回答下列问题。
#include <stdio.h>#include <stdlib.h>/*单链表结点类型*/typedef struct {int xh; /*学号*/float sg; /*身高*/int sex; /*性别,0为男生,1为女生*/} datatype;typedef struct node{datatype data; /*数据域*/struct node *next; /*指针域*/} LinkNode, *LinkList;/*带表头的单链表的基本运算函数*/LinkList initList();/*置一个空表(带头结点)*/void createList_1(LinkList head);/*创建单链表*/void createList_2(LinkList head);/*创建单链表*/void sort_xh(LinkList head);/*单链表排序*/void reverse(LinkList head);/*单链表倒置*/void Error(char *s);/*自定义错误处理函数*/void pntList(LinkList head);/*打印单链表*/void save(LinkList head,char strname[]);/*保存单链表到文件*//*置一个空表*/LinkList initList(){ LinkList p;p=(LinkList)malloc(sizeof(LinkNode));p->next=NULL;return p;}/*创建单链表*/void createList_1(LinkList head){ FILE *fp;int xh;float sg;int sex;LinkList p;if((fp=fopen("records.txt","r"))==NULL){ Error("can not open file !");return ;}while(!feof(fp)){ fscanf(fp,"%d%f%d",&xh,&sg,&sex);p=(LinkList)malloc(sizeof(LinkNode));p->data.xh=xh;p->data.sg=sg;p->data.sex=sex;p->next=head->next;head->next=p;}fclose(fp);}/*创建单链表*/void createList_2(LinkList head){ FILE *fp;int xh;float sg;int sex;LinkList p,rear;if((fp=fopen("records.txt","r"))==NULL){ Error("can not open file !");return ;}rear=head;while(!feof(fp)){ fscanf(fp,"%d%f%d",&xh,&sg,&sex);p=(LinkList)malloc(sizeof(LinkNode));p->data.xh=xh;p->data.sg=sg;p->data.sex=sex;p->next=NULL;rear->next=p;rear=p;}fclose(fp);}/*单链表排序*/void sort_xh(LinkList head){LinkList q,p,u;p=head->next;head->next=NULL;/*利用原表头结点建新的空表*/while(p){ q=p; /*q为被插入的结点*/p=p->next;/*用p记录后继结点*//*遍历新链表查找插入位置*/u=head;while(u->next!=NULL)/*查找插入位置*/{ if(u->next->data.xh>q->data.xh)break;u=u->next;}/*插入在u结点的后面*/q->next=u->next;u->next=q;}}/*单链表倒置*/void reverse(LinkList head){ LinkList p, r;p=head->next;head->next=NULL;while(p){ r=p;p=p->next;/*r指向结点头插到链表*/r->next=head->next;head->next=r;}}/*输出单链表*/void pntList(LinkList head){ LinkList p;p=head->next;while(p!=NULL){printf("%2d: %.2f %d\n",p->data.xh,p->data.sg,p->data .sex);p=p->next;}}/*自定义错误处理函数*/void Error(char *s){ printf("\n %s", s);exit(1); /*返回OS,该函数定义在stdlib.h中*/}/*保存单链表到文件*/void save(LinkList head,char strname[]){ FILE *fp;LinkList p;if((fp=fopen(strname,"w"))==NULL){ printf("can not open file !");return ;}p=head->next;while(p!=NULL){ fprintf(fp,"%2d %5.2f %2d\n",p->data.xh,p->data.sg,p->data.sex);p=p->next;}fclose(fp);}请回答下列问题:(1)由单链表结点类型定义可知,该链表结点类型名为 LinkNode ,结点的指针类型为 LinkList ,向系统申请一个学生结点空间并把起始地址存于上述结点指针变量new 中的语句是: p=(LinkList)malloc(sizeof(LinkNode)); 。
数据结构多项式相加实验报告篇一:数据结构实验多项式加法数据结构实验报告实验名称:多项式加减法学号:1XX10419姓名:林强实验日期:XX.5.05一、实验目的通过实现多项式的加减法,对链表有更深入的了解二、实验具体内容1、实验题目1:(1)题目设计一个一元稀疏多项式简单的加减法计算器实现要求:一元稀疏多项式简单计算器的基本功能是:(1)输入并建立多项式:A(x)?7?3x?9x8?5x17;B(x)?8x?22x7?9x8(2)输出多项式(3)多项式A和B相加,建立多项式C=A+B,并输出相加的结果多项式C(4)选作:多项式A和B相减,建立多项式C=A-B,并输出相加的结果多项式D(2)分析1:本程序的任务是实现两个多项式的加法其中多项式的系数为浮点型,指数为整数,输出的结果也为系数和指数。
(1)输入的形式和输入值的范围:输入多项式的系数a和未知数X的指数b,当a和b都为零时,输入结束。
输入值的范围:a为实数,b为整数。
(2)输出形式:输出多项式的系数和多项式未知数X 的指数即(a,b)形式。
(3)程序所能达到的功能,实现两个多项式的加法,并输出最后的结果2:整个程序运行期间实行动态创建节点,一边输入数据,一边创建节点当将全部数据输入到单链表中后再调用多项式加法这个函数,并一边实现多项式的相加,一边释放节点,有效防止了在程序反复运行过程中可能出现系统空间不够分配的现象(3)实验代码typedef int Status;#define OVERFLOW -1#define null 0typedef struct Lnode{float coef; //存储项系数int expn;//存储项指数struct Lnode *next;}Lnode,*LinkList;typedef LinkList polynomial;Status InitList_L(LinkList &L) {//初始化头节点L=(LinkList)malloc(sizeof(Lnode));if(!L)return(-1);L->next=null;return 1;}void AddPolyn(polynomial pa, polynomial pb){ //实现两个多项式相加的算法float x;polynomial qa;polynomial qb;polynomial s;polynomial u;qa=pa->next; qb=pb->next; s=pa;while(qa&&qb){if(qa->expnexpn){s=qa;qa=qa->next;}else if(qa->expn==qb->expn){x=qa->coef+qb->coef;if(x!=0){qa->coef=x;s=qa;qa=qa->next;u=qb;qb=qb->next;free(u);}else{s->next=qa->next;free(qa);qa=s->next;u=qb;qb=qb->next;free(u);}}else if(qa->expn>qb->expn){ u=qb->next;s->next=qb;s=qb;qb->next=qa;qb=u;}}if(qb)qa->next=qb;free(pb);}void main(){float a;int b;polynomial L1;polynomial L2; LinkList q;LinkList p;LinkList m;LinkList n;InitList_L(L1);q=L1;InitList_L(L2);p=L2;cout 请输入数据:" for(;;){ cin>>a;cin>>b;if(a==0&&b==0) break;m=new Lnode;m->coef=a;m->expn=b;q->next=m;q=m;q->next=null;}//循环输入第一个多项式的系数与指数for(;;){cin>>a;cin>>b;if(a==0&&b==0)break;n=new Lnode;n->coef=a;n->expn=b;p->next=n;p=n;p->next=null;}//循环输入第二个多项式的系数与指数AddPolyn(L1,L2);//调用多项式相加的算法while((L1->next)!=null){coutnext->coefnext->expn L1=L1->next;}//输出计算结果}三、实验小结通过编写多项加法这个程序,我将自己所学到的创建链表,初始化链表和多项式加法算法都应用了一次,这使我们不仅仅只是理论化的学习书本上的知识,而是将学习到的理论知识应用到实际的操作中来增强我们的实际操作能力,这使我增加了实际操作经验,也使我通过实际操作来认识到自己在程序编写上的不足从而增强了我的实际编写程序的能力。
简单介绍:本次作业力在学会链表表示线性表的插入、删除、查找等基本操作设计与实现,学习利用链表提供的接口去求解实际问题,同时熟悉链表的的存储方法。
再基于线性链表的基础设计完成多项式的相加运算程序。
一、实验目的和要求完成多项式的相加、相乘运算。
(1)掌握线性表的插入、删除、查找等基本操作设计与实现(2)学习利用线性表提供的接口去求解实际问题(3)熟悉线性表的的存储方法二、实验内容和原理1.实验内容设计一个一元多项式的简单计算程序,其基本功能有:(1)输入并建立多项式;(2)输出多项式;(3)多项式的相加运算。
利用单链表实现。
2.实验原理使用单链表实现一元多项式的存储,并实现两个一元多项式的加法运算。
三、实验环境硬件:(1)学生用微机(2)多媒体教室或远程教学(3)局域网环境软件:(1)Windows XP中文操作系统(2)VC6.0四、算法描述及实验步骤1、描述:加法:输入建立一元多项式,进行简单加法运算,输出结果;通过建立单链表A和B分别存放多项式的a和b的各项系数及指数;并且利用A使得不产生新的节点而在A中存放数据运算结果;该过程通过定义指针变量p和q使它们分别指向两个多项式的第一个节点,之后依次比较它们所指向的项的指数,即一种情况指数相等时系数相加且和不为零,修改当前p所指项的系数(和),同时删除q所指项,若和为零则同时删除p和q各自所指;情况二,p当前项指数大于q当前项,将q所指插入p所指之前作为结果项之一;情况三,p当前项指数小于q当前项,p所指作为多项式和的一项,移动p指向下一项,进行比较,在移动p,q至其中以个链空,把另一个链余下节点插在p所指之后;乘法:定义指针p,q指向所操作节点,通过A链表的每一项与B链表各项相乘,指数相加,系数相乘,将值赋给新节点各自域,构成一新的链表,最后返回头结点。
可这样有一个问题,即新生成的链表,即最终结果混乱,没有对数据进行过滤,相同指数项应在执行加法运算,所以可以这样实现,通过A链表的每一项与B链表各项相乘的新生成节点单独构成一链表,并将第一个链表加入另一新链表,循环此操作将后生成的链表加之先前的链表,即可实现排序问题。
实验链表实验报告一、实验目的本次实验的主要目的是深入理解链表这种数据结构的概念、特点和操作方法,并通过实际编程实现来提高对链表的应用能力。
二、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。
三、实验原理链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
与数组不同,链表的内存分配是动态的,并且可以方便地进行插入和删除操作,而不需要移动大量的元素。
链表分为单向链表、双向链表和循环链表等多种类型。
在本次实验中,我们主要实现单向链表。
单向链表的节点结构通常包含数据域和指针域。
数据域用于存储节点的数据,指针域用于指向下一个节点。
通过遍历链表的指针,可以访问链表中的每个节点。
四、实验内容1、链表节点的定义```cppstruct ListNode {int data;ListNode next;ListNode(int x) : data(x), next(NULL) {}};```2、链表的创建```cppListNode createList(){ListNode head = NULL;ListNode tail = NULL;int num;cout <<"请输入链表中的数字(输入-1 结束):";cin >> num;while (num!=-1) {ListNode newNode = new ListNode(num);if (head == NULL) {head = newNode;tail = newNode;} else {tail>next = newNode;tail = newNode;}cin >> num;}return head;}```3、链表的遍历```cppvoid traverseList(ListNode head) {ListNode curr = head;while (curr!= NULL) {cout << curr>data <<"";curr = curr>next;}cout << endl;}```4、链表的插入```cppvoid insertNode(ListNode& head, int position, int value) {ListNode newNode = new ListNode(value);if (position == 0) {newNode>next = head;head = newNode;return;}ListNode curr = head;int count = 0;while (curr!= NULL && count < position 1) {curr = curr>next;count++;}if (curr == NULL) {cout <<"插入位置超出链表长度" << endl; return;}newNode>next = curr>next;curr>next = newNode;}```5、链表的删除```cppvoid deleteNode(ListNode& head, int position) {if (head == NULL) {cout <<"链表为空,无法删除" << endl; return;}if (position == 0) {ListNode temp = head;head = head>next;delete temp;return;}ListNode curr = head;ListNode prev = NULL;int count = 0;while (curr!= NULL && count < position) {prev = curr;curr = curr>next;count++;}if (curr == NULL) {cout <<"删除位置超出链表长度" << endl; return;}prev>next = curr>next;delete curr;}```五、实验结果通过对上述链表操作函数的调用,我们成功地创建、遍历、插入和删除了链表中的节点。
通信韩若冰222010315220106实验项目:线性表及其应用实验内容:用单链表存储多项式;实现多项式的输出显示、相加、相乘、求导、求值运算。
算法设计与程序实现:由于存储多项式需要存储系数和指数,且其指数变化范围可能很大如果用顺序表就会浪费很大的空间,用单链表存取指针域,和数据域(系数和指数)就会节省很大空间。
要想实现多项式的显示,相加,相乘,求导,求值运算,首先得创建函数以实现上述功能,然后再在主函数中调用上述函数以得到运行结果。
算法描述:(实验内容的核心算法)创建链表:首先创建空表,然后将每个结点用尾插法依次插入。
每一项多项式的组成部分(系数和指数)输出程序:此程序需要遍历整个链表,通过判断p->next的系数的正负来确定输出“+”还是“-”很容易出现错误。
多项式相加:这个程序需要按照幂的排列顺序依次遍历寻找一个多项式与另一个多项式指数相同的,将其系数相加比较简单。
该程序写成升幂比较,其中可能出现如A多项式的前几项都比B中的指数小,那么以一个pre为头结点的链表先将其穿起来,找到相等的进行运算再串起来,最后可能会有链表剩余的指数更大的项不能和另一个相加再将剩余的串起来。
(第一项要先串起来,因为第一项之前没有多项式不用判断+ —号)多项式相乘:此程序需要循环语句,即将一个多项式的每一项分别和另一个多项式相乘,依次调用多项式相加的程序叠加起来。
多项式求导:需要依次将多项式的每一项的系数和指数相乘,指数减1,形成一个链表多项式求值:需要有x的幂次的表示,C语言不能识别“^”,所以需要用一个循环实现x^exp相乘的结果,容易出错核心程序:运行结果:实验总结:本次试验做了很长时间,也出现了很多错误。
总起来说有以下几种错误:1.输入错误:中英文状态下输入错误,其中还有运行时在中文状态下输入数据回车后就不能输了,应在英文状态下输入data , data↙2.多项式表示需要判断下一个多项式系数是正还是负然后分别写+, —(fabs),但是第一项必须先输出,因为第一项不需要写+ —号3.多项式相加,要注意写的程序是怎么比较的,升幂的话则p->exp < q->exp 则把p结点指数小的先穿起来。
实验名称多项式加法的链表设计与实现实验方案实验成绩实验日期实验室信息系统设计与仿真室I 实验操作
实验台号班级姓名实验结果
一、实验目的
1、掌握多项式链表结构的设计;
2、掌握多项式结点的创建、插入、释放等操作;
3、编程实现多项式链表的文件读入、加法求和以及输出显示功能。
二、实验任务
设计一元多项式的加法程序,其基本功能有
①从文件中读取一元多项式;格式: 5X3+4X2+3X+2
②实现两个多项式相加;
③输出结果多项式;
运用单链表存储多项式,结果链表使用原链表空间。
三、实验设计方案
1.多项式结构体设计
思路:应包含系数项、指数项和后继指针项。
struct ploy{
int ceof; //系数
int exp; //指数
struct ploy *next;
};
typedef struct ploy Ploy;
2.自定义函数设计
(1)从文件读取多项式
思路:按照文件in.txt格式读取多项式,注意判断各种符号情况:符号位、系数、x、指数。
Ploy *input()
{
int ceof=1,exp=0,sign=1; //赋初始值: 系数为1, 指数为0, 符号为1 (正)
int c2e=0; //标记变量: 表示准备读入系数还是指数(0表示系数, 1表示指数)
char str[20],*p=str; //str用于存放读入的多项式
Ploy *pa=newnode(0,0); //创建链表头结点.
Ploy *t=pa; //队尾指针初始值为头指针
scanf("%s",str); //读入多项式到str
while(*p!='\0'){ //将多项式系数和指数写入到链表结点中
if(*p=='+' || *p=='-') //如果是符号+或-
{
if (c2e) //如果c2e为1,表示已经读入指数,可以将系数和指数插入链表结点t=insert(t,ceof,exp); //尾插法
sign= (*p=='+' ? 1 : -1); //取符号位
exp=0; //符号位读完后,接下来要读入系数和指数,赋指数系数默认值
ceof=1;
c2e=0; //表示接下来要读入系数
}
else if(*p>='0' && *p<='9' && c2e==0) //表示读入的系数
ceof=(*p-'0')*sign;
else if (*p=='X' || *p=='x'){ //表示读入的是x
c2e=1; //表示接下来要读入指数
exp=1; //指数默认值赋为1
}
else if(*p>='0' && *p<='9' && c2e==1) //表示读入的是指数
exp=*p-'0';
p++; //转移到下一个字符
}
t=insert(t,ceof,exp); //插入最后一项(系数和指数)
return pa;
}
(2)多项式加法
思路:分三种情况把多项式1和多项式2中的各项链接到和多项式中。
Ploy *add(Ploy *ha, Ploy *hb)
{
Ploy *pa,*pb,*q; //pa和pb指向多项式1和2的当前项, q表示和多项式的当前项.
pa=ha->next; //初始化pa, pb和q
pb=hb->next;
q=ha;
free(hb); //用多项式1的头结点作为和多项式的头结点,故释放多项式2的头结点hb.
while(pa!=NULL && pb!=NULL){ // 比较多项式1和多项式2两个当前项的指数if(pa->exp > pb->exp){ //多项式1的指数大
q->next=pa; // 链接到和多项式指针q的后面
q=pa; // 修改q
pa=pa->next; // 多项式1当前项后移
}
else if (pa->exp < pb->exp){ //多项式2的指数大
q->next=pb;
q=pb;
pb=pb->next;
}
else{ //多项式1和2的指数相等
int x=pa->ceof+pb->ceof; // 计算两项的系数之和
Ploy *r; //用于指示准备释放的结点
if(x) { //如果系数之和不为0
pa->ceof=x; // 修改多项式1当前项的系数项
q->next=pa; //将多项式1的当前项接到和多项式q后面
q=pa; // 修改q
pa=pa->next; //pa指针后移
r=pb; //r存放pb当前项, 准备释放该结点空间
pb=pb->next; //pb后移
free(r); //释放r
}
else{ //如果系数为0
r=pb; //准备释放pb当前项
pb=pb->next;
free(r);
r=pa; //准备释放pb当前项
pa=pa->next;
free(r);
}
}
}
if(pa==NULL && pb==NULL) //多项式1和2均为空, q的指针域赋结束标记NULL q->next=NULL;
else if(pa!=NULL) //多项式1不空, 剩余项接到q后面
q->next=pa;
else //多项式2不空, 剩余项接到q后面
q->next=pb;
return ha;
}
(3)输出和多项式
思路:注意第1项没有正符号位, 以后各项最好按符号,系数,X和指数分开显示.
void output(Ploy *p)
{
p=p->next;
if(p!=NULL) //显示第1项
printf("%dX%d",p->ceof,p->exp);
p=p->next;
while(p!=NULL){
if(p->ceof>0) //符号位
printf("+");
printf("%d",p->ceof); //系数
if(p->exp>0) //X
printf("X");
if(p->exp>1) //指数
printf("%d",p->exp);
p=p->next;
}
printf("\n");
}
(4)给出创建结点函数newnode()和插入结点函数insert()的函数原型, 请编程完成. Ploy *newnode(int c, int e);
Ploy *insert(Ploy *p, int c, int e);
3.主函数设计
思路:主函数实现实验任务的基本流程。
void main()
{
Ploy *pa, *pb;
freopen("in.txt","r",stdin);
pa=input(); //读入多项式1
pb=input(); //读入多项式2
pa=add(pa,pb); //两个多项式相加
output(pa); //输出和多项式
}
四、测试
1、测试数据
下面测试数据存放在in.txt文件中:
5X3+4X2+3X+2
2X2+X+1
2、测试结果
测试结果显示如下:
5X3+6X2+4X+3
五、总结与讨论
1、问题与错误
2、经验与收获
3、改进与设想
六、源代码。