实验报告格式规范,包括以下内容:(正文 宋体五号 )

一、问题描述(标题黑体小四)

对简单的一元多项式相加、相减、求导运算。

二、实验目的

实现对简单的一元多项式相加、相减、求导运算。

三、实验设计

1.逻辑结构

逻辑结构是指数据元素之间的逻辑关系,即从逻辑关系上描述数据。它与数据的存储无关,是独立于计算机的。数据的逻辑结构分为线性结构和非线性结构,线性表是典型的线性结构;集合、树和图是典型的非线性结构。数据的逻辑结构分类见图1-1。

  • 集合结构中的数据元素之间除了 “同属于一个集合”的关系外,别无其他关系。
  • 线性结构结构中的数据元素之间只存在一对一的关系。
  • 树形结构结构中的数据元素之间存在一对多的关系。
  • 图状结构或网状结构结构中的数据元素之间存在多对多的关系。

一般来讲,一个一元多项式,按照升幂写成

多项式由(n+1)个系数唯一确定,按照原理上可以用线性表P来表示,实现计算机处理。

2.存储结构

存储结构是指数据结构在计算机中的表示(又称映像),也称物理结构。它包括数据元素的表示和关系的表示。数据的存储结构是逻辑结构用计算机语言的实现,它依赖于计算机语言。数据的存储结构主要有:顺序存储、链式存储、索引存储和散列存储。

  • 顺序存储:把逻辑上相邻的元素存储在物理位置上也相邻的存储单元里,元素之间的关系由存储单元的邻接关系来体现。其优点是可以实现随机存取,每个元素占用最少的存储空间;缺点是只能使用相邻的一整块存储单元,因此可能产生较多的外部碎片。
  • 链接存储:不要求逻辑上相邻的元素在物理位置上也相邻,借助指示元素存储地址的指针表示元素之间的逻辑关系。其优点是不会出现碎片现象,充分利用所有存储单元;缺点是每个元素因存储指针而占用额外的存储空间,并且只能实现顺序存取。
  • 索引存储:在存储元素信息的同时,还建立附加的索引表。索引表中的每一项称为索引项,索引项的一般形式是:(关键字,地址)。其优点是检索速度快;缺点是增加了附加的索引表,会占用较多的存储空间。另外,在增加和删除数据时要修改索引表,因而会花费较多的时间。
  • 散列存储:根据元素的关键字直接计算出该元素的存储地址,又称为Hash存储。其优点是检索、增加和删除结点的操作都很快;缺点是如果散列函数不好可能出现元素存储单元的冲突,而解决冲突会增加时间和空间开销。

如果用顺序表p[n]进行存储,下标代表指数,所存储的值代表系数。这样便可实现多个一元多项式的相加相减以及求导运算。但是对于处理

就需要开辟长度为1001的线性表,显然浪费空间。故可以将指数和系数分开存储。
一般情况下,对于一元n次多项式可以写成

显然,可以用一个长度为m且每个元素包含俩个数据项(系数项和指数项)的线性表((p1,e1),(p2,e2),…,(pn,en))唯一确定多项式p(x)。
线性表有两种存储结构,相应的采用线性表表示的一元多项式也有两种存储结构。如果只对多项式“求值”等不改变多项式的系数和指数的运算,则可以用顺序存储结构,否则应该采用链式存储结构。本次对一元多项式的操作是相加相减求导运算,故需要使用链式存储结构

比如
如下图所示,为一元多项式 A(x)=7+3x+9x8+5x17 和 B(x)=8x+22x7-9x8 的链表表示图:

一元多项式的存储结构定义描述如下:

typedef struct
{float coef;//系数int expn;//指数struct UNARY *next;//指针域
} UNARY;

3.算法设计思想

如果两个多项式相加(减),根据两个多项式相加的规则:两个指数项相同的对应系数相加(减),如果系数和(差)不为零,则和(差)作为系数和指数一起构成“和(差)多项式”;如果两个系数不同,则分别复制“和(差)多项式”中去。

当两个一元多项式相加时,需遵循如下的运算规则。假设指针 qa 和qb 分别指向多项式 A 和多项式 B 中当前进行比较的某个结点,则比较两个结点的指数项,有以下 3 种情况:

  • 指针 qa 所指结点的指数值小于指针 qb 所指结点的指数值,则应摘除 qa 所指结点插入到“和多项式”链表中去;
  • 指针 qa 所指结点的指数值大于指针 qb 所指结点的指数值,则应摘除 qb 所指结点插入到“和多项式”链表中去;
  • 指针 qa 所指结点的指数值等于指针 qb 所指结点的指数值,则将两个结点的系数相加:若和不为 0 ,则修改 qa 所指结点的系数值,- 同时释放qb所指结点;若和为 0,则应从多项式 A 的链表中删除相应结点,并释放指针 qa 和 qb 所指结点。

如果对多项式进行求导,根据多项式的求导规则:系数与指数相乘,指数减1;如果指数为零,本项为零,不再复制到新的多项式中

4.输入、输出设计

输入设计
首先对第一个链表进行输入
输入格式(系数+指数)
每次对是否继续输入该链表进行输入判断
输入格式(1:继续 0:结束)

输入选择
输入格式(1:求导,2:加减运算)

输入运算类型
输入格式(+/-)

输出设计
依次输出链表中的系数和指数
输出格式(系数+指数)

四、主要代码

/**对一元多项式进行升幂排序*输入:一元多项式链表*输出:升幂排序的一元多项式链表*
*/
UNARY* Increasing(UNARY *LA,UNARY *LB)
{UNARY *head,*end,*pre,*cur,*next,*temp;head = LA;//以及LBend = NULL;//冒泡排序:将 最小/最大 的节点后移至当前的最后一位。while(head->next != end){for(pre = head,cur = head->next,next = cur->next; next != end; pre = pre->next,cur = cur->next,next = next->next){if(cur->expn > next->expn){cur->next = next->next;pre->next = next;next->next = cur;temp = next;next = cur;cur = temp;}}end = cur;}
}
float  add_ab(float A,float B)
{return A+B;
}
float subtract_ab(float A,float B)
{return A - B;
}//升幂的一元多项式的相加与相减
UNARY* unaryAdd_Sub(UNARY *LA,UNARY *LB,char method)
{//LA作为输出链UNARY *r,*s,*p,*q;int cmp;p = LA->next;//用于比较q = LB->next;//用于比较s = LA;//用于记录p的前置r = LB;//用于记录q的后置while(p!=NULL && q!=NULL){if(p->expn<q->expn) cmp = -1;//当p指数小于q指数,p后移else if(p->expn>q->expn) cmp = 1;//当p指数大于q指数,q为p的前置,q后移else cmp = 0;//pq指数相同,进行加/减运算switch(cmp){case -1:{s = p;p = p->next;};break;case 0:{float x;if(method == '+'){x = add_ab(p->coef,q->coef);}else if(method == '-'){x = subtract_ab(p->coef,q->coef);}if((int)x!=0){p->coef = x;s = p;p = p->next;r->next =q->next;free(q);q = r->next;}else{//删除LA节点s->next = p->next;free(p);p = s->next;//删除LB节点r->next =q->next;free(q);q = r->next;}};break;case 1:{r->next = q->next;q->next = s->next;s->next = q;s = q;q = r->next;};break;}}if(q!=NULL){//因为 前面的结束条件 p = null 所以 p的前置s位于链表的尾部,s连接qs->next = q;}free(LB);return LA;}
/*对一元多项式进行求导*输入:一元多项式链表*输出:求导后的一元多项式链表*所谓求导:系数与指数相乘,指数减1;如果指数为零,本项为零,不再复制到新的多项式中
*/UNARY* Derivation(UNARY *LA,UNARY *LB)
{UNARY *headLA,*headLB;headLA = LA;headLB = LB;while(headLA->next!=NULL){headLA = headLA->next;headLA->coef = headLA->coef*headLA->expn;if(headLA->expn!=0){headLA->expn -= 1;}else{headLA->expn = 0;}}while(headLB->next!=NULL){headLB = headLB->next;headLB->coef = headLB->coef*headLB->expn;if(headLB->expn!=0){headLB->expn -= 1;}else{headLB->expn = 0;}}}

五、程序运行结果截图


六、遇到的问题和解决方法

问题:刚开始考虑的一元多项式默认是升幂,对于乱序的一元多项式不知道如何解决
解决方法:对乱序的一元多项式进行排序,首先考虑的是值传递 但是代码过于复杂,无论是时间复杂度,还是空间复杂度 都高于地址交换
唯一的好处是逻辑简单;故本次采用地址交换的方式进行对乱序的一元二次多项式进行升幂排序,主要算法就是冒泡排序;需要6个节点并且是前后继的关系,每次后移加判断;
问题:对于’零‘这个特殊项的处理
解决方法:1.如果零系数出现在定义多项式阶段,直接不进行连接主链表,并且释放该空间
2.如果零系数出现在加减运算阶段,进行删除两链表节处理,并且释放该空间
3.如果零指数出现在求导运算阶段,删除节点,并释放空间

七、完整代码

点击查看代码

#include <stdio.h>
#include <stdlib.h>
typedef struct
{float coef;//系数int expn;//指数struct UNARY *next;
} UNARY;float  add_ab(float A,float B)
{return A+B;
}
float subtract_ab(float A,float B)
{return A - B;
}//升幂的一元多项式的相加与相减
UNARY* unaryAdd_Sub(UNARY *LA,UNARY *LB,char method)
{//LA作为输出链UNARY *r,*s,*p,*q;int cmp;p = LA->next;//用于比较q = LB->next;//用于比较s = LA;//用于记录p的前置r = LB;//用于记录q的后置while(p!=NULL && q!=NULL){if(p->expn<q->expn) cmp = -1;//当p指数小于q指数,p后移else if(p->expn>q->expn) cmp = 1;//当p指数大于q指数,q为p的前置,q后移else cmp = 0;//pq指数相同,进行加/减运算switch(cmp){case -1:{s = p;p = p->next;};break;case 0:{float x;if(method == '+'){x = add_ab(p->coef,q->coef);}else if(method == '-'){x = subtract_ab(p->coef,q->coef);}if((int)x!=0){p->coef = x;s = p;p = p->next;r->next =q->next;free(q);q = r->next;}else{//删除LA节点s->next = p->next;free(p);p = s->next;//删除LB节点r->next =q->next;free(q);q = r->next;}};break;case 1:{r->next = q->next;q->next = s->next;s->next = q;s = q;q = r->next;};break;}}if(q!=NULL){//因为 前面的结束条件 p = null 所以 p的前置s位于链表的尾部,s连接qs->next = q;}free(LB);return LA;}
UNARY* creatList(UNARY *LA,UNARY *LB)
{LA->next = NULL;LB->next = NULL;UNARY *node;int choice;int i = 1;while(1){printf("输入LA序列的第%d元素的系数+指数(格式:系数 指数)",i);node =  (UNARY*)malloc(sizeof(UNARY));if(node==NULL){exit(0);}scanf("%f %d",&node->coef,&node->expn);//不合法分析:1、系数为零 (√)2、指数重复(未解决)if(node->coef==0){continue;}node->next = LA->next;LA->next = node;i++;printf("继续?(1,0)");scanf("%d",&choice);if(choice==0){break;}}while(1){printf("输入LB序列的第%d元素的系数+指数(格式:系数 指数)",i);node =  (UNARY*)malloc(sizeof(UNARY));scanf("%f %d",&node->coef,&node->expn);node->next = LB->next;LB->next = node;i++;printf("继续?(1,0)");scanf("%d",&choice);if(choice==0){break;}}}
UNARY* printList(UNARY *LA,UNARY *LB)
{UNARY *circleLA,*circleLB;circleLA = LA;circleLB = LB;printf("LA:\n");while(circleLA->next!=NULL){circleLA = circleLA->next;printf("%.2f %d\n",circleLA->coef,circleLA->expn);}printf("LB:\n");while(circleLB->next!=NULL){circleLB = circleLB->next;printf("%.2f %d\n",circleLB->coef,circleLB->expn);}
}
/*对一元多项式进行升幂排序*输入:一元多项式链表*输出:升幂排序的一元多项式链表*
*/
UNARY* Increasing(UNARY *LA,UNARY *LB)
{UNARY *head,*end,*pre,*cur,*next,*temp;head = LA;end = NULL;//冒泡排序:将 最小/最大 的节点后移至当前的最后一位。while(head->next != end){for(pre = head,cur = head->next,next = cur->next; next != end; pre = pre->next,cur = cur->next,next = next->next){if(cur->expn > next->expn){cur->next = next->next;pre->next = next;next->next = cur;temp = next;next = cur;cur = temp;}}end = cur;}head = LB;end = NULL;while(head->next != end){for(pre = head,cur = head->next,next = cur->next; next != end; pre = pre->next,cur = cur->next,next = next->next){if(cur->expn > next->expn){cur->next = next->next;pre->next = next;next->next = cur;temp = next;next = cur;cur = temp;}}end = cur;}}
/*对一元多项式进行求导*输入:一元多项式链表*输出:求导后的一元多项式链表*所谓求导系数与指数相乘,指数减1;如果指数为零,本项为零,不再复制到新的多项式中
*/UNARY* Derivation(UNARY *LA,UNARY *LB)
{UNARY *headLA,*headLB;headLA = LA;headLB = LB;while(headLA->next!=NULL){headLA = headLA->next;headLA->coef = headLA->coef*headLA->expn;if(headLA->expn!=0){headLA->expn -= 1;}else{headLA->expn = 0;}}while(headLB->next!=NULL){headLB = headLB->next;headLB->coef = headLB->coef*headLB->expn;if(headLB->expn!=0){headLB->expn -= 1;}else{headLB->expn = 0;}}}int main()
{int choice;//创建链表UNARY *LA,*LB;LA = (UNARY*)malloc(sizeof(UNARY));LB = (UNARY*)malloc(sizeof(UNARY));creatList(LA,LB);//将链表变为升幂次序Increasing(LA,LB);printf("升幂后\n");printList(LA,LB);printf("输入选择(1:求导 2:运算):");scanf("%d",&choice);if(choice ==1)
{//求导:将系数与指数相乘 然后指数减1Derivation(LA,LB);printf("求导后\n");printList(LA,LB);}
else if(choice == 2)
{//运算(加减运算)char x;printf("运算:");scanf("\n");scanf("%c",&x);unaryAdd_Sub(LA,LB,x);printf("运算后\n");printList(LA,NULL);}}

文章主要摘自《深入浅出数据结构与算法》————清华出版社

【数据结构】一元多项式相关推荐

  1. 数据结构-一元多项式加减程序

    //一元多项式加减程序 //程序:张建波 //时间:2005/7/12 PM:20-08 //功能: //     1:可以计算 1+2+3-1+2-5+6+3 (加减法均可) //     2: 可 ...

  2. 数据结构—— 一元多项式的加法运算

    一. 需求分析 0.问题描述 在数学上,一个一元n次多项式 可按降序写成: 它由n+1个系数唯一确定,因此,在计算机里他可以用一个线性表表示: 设Pn(x)和Qn(x)分别为两个一元多项式,请求出两个 ...

  3. 数据结构——一元多项式相加(C语言版本)

    本关任务:设计一种单链表存储结构,每个结点存储一项的系数和指数,类型都是整型,编写完成产生多项式的函数.多项式相加及输出多项式的函数. 相关知识 为了完成本关任务,你需要掌握: 如何存储一个一元多项式 ...

  4. 数据结构 - 一元多项式相加减(C语言)

    通常情况下,一元多项式可写成: an(x) = a1x^e1 + a2x^e2 + a3x^e3 + ... + amx^em (数字,m为下标),其中:pi是指数为ei的项的非零系数,0<= ...

  5. 数据结构一元多项式求导_Joahua的数据结构笔记(二)

    说明:以下笔记中,代码全为伪代码,请自行阅读与理解.下一篇文章即将用一个小小的实验题来对文章内容进行验证和实现. 文章结尾将会放出实验题,可以先行思考. 第一章 线性表 2.1 线性表的定义和特点 定 ...

  6. 数据结构--一元多项式

    函数功能说明: Void InitList(PolyNode &L) /初始化多项式单链表*/ Int GetLength(PolyNode*L) /求多项式单链表的长度/ PolyNode ...

  7. 数据结构—— 一元多项式的运算(相加,相减,相乘)【C语言实现】

    用 C语言实现一元多项式的运算(相加,相减,相乘) 1.创建多项式时,无论指数项按什么顺序输入,输出均能实现以升幂顺序输出,且输入时有相同指数项时能够实现合并. 2.能够代入确切的X计算出最终多项式的 ...

  8. C语言数据结构一元多项式

    //定义多项式最大项数#include<stdio.h>#include<malloc.h>#define MAX 20//定义存放多项式的数组类型typedef struct ...

  9. 数据结构一元多项式的相加-单链表实现

    实验内容:把任意给定的两个一元多项式P(x) ,Q(x) 输入计算机,计算它们的和并输出计算结果. 一元多项式可以用单链表表示,结点结构图示如下: coef  exp next 首先分析一下这个过程是 ...

  10. 数据结构之链表创建一元多项式,求一元多项式之和

    数据结构之链表创建一元多项式,求一元多项式之和 前言 对于一元多项式,我们完全可以利用线性表P(a0,a1,a2,-,an)表示,这样的线性表在求两个多项式相加等操作时确实简单,但是多于如下的多项式: ...

最新文章

  1. Linux学习(一)--目录结构
  2. OPMS 1.2 版本更新发布
  3. SAP CRM product hierarchy和category的三个问题问答
  4. javafx弹出式窗口_JavaFX 8的弹出式编辑器
  5. 关于微信浏览器H5 React,Vue工程化项目input无法自动聚焦疑难杂症排查
  6. as和java什么关系_深入理解happens-before和as-if-serial语义
  7. oracle procedures批量删除带索引条件数据很慢_redis数据结构、持久化、缓存淘汰策略...
  8. linux 进程间广播,Linux系统编程之进程间通信之浅谈信号
  9. php和vue实现智商在线测试题
  10. mac 思科 链路聚合_链路聚合定义/Eth-trunk/思科华为配置实例
  11. 【场景化解决方案】金蝶凭证信息与OA审批集成
  12. 希捷硬盘查询保修期限的网址
  13. touch.pageX/touch.screenX/touch.clientX的区别
  14. 奔腾处理器_编号和非编号的奔腾处理器之间有什么区别?
  15. element-ui中的表格组件实现隔行换色
  16. Linux下串口的配置
  17. src中的 “/”、“./”与“../”
  18. certificate has expired
  19. 【转】知识图谱上推荐推理的模仿学习框架
  20. 25匹马,5个跑道,每次只能跑5匹,用最少的次数选出最快的前3匹

热门文章

  1. 计划的主体部分应有哪些内容_计划的正文主体一般有哪三个部分构成
  2. 数据挖掘进行数据分析常用的方法
  3. Ubuntu 18.04 安装搜狗拼音
  4. CSS知识回顾(10)
  5. 组合数的几种常规求法
  6. c语言程序设计迷宫问题,C语言迷宫问题
  7. [我一直想看到的文章 好好保存赏析]微软、英特尔和摩根的比较
  8. Win11怎么共享文件夹?Win11创建共享文件夹的方法
  9. 升级主板和CPU后OpenGL初始化失败问题的解决
  10. 微服务开源生态报告 No.1