参考书籍:数据结构(C语言版) 严蔚敏 吴伟民编著 清华大学出版社

本文中的代码可从这里下载:https://github.com/qingyujean/data-structure

1.简要说明

    一元多项式的表示和相加

多项式Pn(x)按升幂可写成:

Pn(x) = P0+P1*x+p2*x^2+...+Pn*x^n,

它由n+1个系数唯一确定,因此可用一个线性表p=(p0,p1,p2,...,pn),每一项的指数i隐含在系数pi的序号里。设Qm(x)是一元m次多项式,则可用线性表Q=(q0,q1,q2,...,qm)来表示。不失一般性,设m<n,则两个多项式想家的结果多项式Rn(x)=Pn(x)+Qm(x)可用线性表:

(p0+q0, p1+q1, ..., pm+qm, p(m+1), ..., pn)

分析:
    对P、Q、R可用顺序存储结构,多项式相加的算法定义将十分简单,但通常应用中次数可能很高,使得顺序存储结构的最大长度很难确定;另外很多项的系数也可能为0,比如S(x)=1+3x^10000+2x^20000,如果是像这样仅有3个非0元素,则顺序存储结构的线性表的存储空间将非常浪费,故采用单链表结构,但是这时就要存储指数了。
    一元n次多项式Pn(x)=p1*x^e1 + p2*x^e2 +...+pm*x^em,其中pi是指数为ei的项的非零系数,且满足0<=e1<e2<...<em=n,若用一个长度为m且每个元素有两个数据项(系数项+指数项)的线性表((p1,e1),(p2,e2),...,(pm,em))便可唯一确定多项式Pn(x)。 最坏情况下,n+1(=m)个系数都不为0,这种表示将大大节省空间。

   实现:
    "和多项式"链表中的节点无需另生成,而应该从两个多项式的链表中摘取。运算规则如下:假设指针qa、qb分别指向多项式A和B中当前进行比较的某个节点,则比较两个节点中的指数项,有下列3种情况:
     1.qa所指节点的指数值<qb所指节点的指数值,则应摘取qa所指节点插入到“和多项式”中;
     2.qa所指节点的指数值>qb所指节点的指数值,则应摘取qb所指节点插入到“和多项式”中;
     3.qa所指节点的指数值=qb所指节点的指数值,则将两节点的系数相加
          3.1若系数相加和数不为0,则修改qa所指节点的系数值,同时释放qb所指节点;
          3.2若系数相加和数为0,从多项式A的单链表中删除相应节点,并释放qa和qb所指节点。
    注意:
    表示一元多项式的应该是有序链表

2.代码实现

#include<stdio.h>
#include<stdlib.h>
#define NULL 0
typedef struct term{float coef;int expn;struct term *next;
}term, *LinkList;//term为一个新类型(是一个结构体),LinkList为指向这样的结构体的指针typedef LinkList polynomial;
int cmp(LinkList qa, LinkList qb){//比较项的指数大小if(qa->expn > qb->expn)return 1;else if(qa->expn == qb->expn)return 0;elsereturn -1;
}
//若有序链表L中存在与项t的指数相等的元素,则指针q指向L中第一个指数为t->expn的节点的位置,
//否则q指向第一个指数满足与t->expn相比>0的节点的前驱位置
bool locateElem(LinkList L, LinkList t, LinkList &q){LinkList p1 = L->next;LinkList p2 = L;//p2总指向p1的前驱while(p1){if(t->expn > p1->expn){p1 = p1->next;p2 = p2->next;}else if(t->expn == p1->expn){q = p1; return true;}else{//p1->expn > t->expn,因为L是有序表,所以如果程序走到了这一步,说明没找到与项t的指数相等的节点元素//则返回q的前驱结点q = p2;return false;}}if(!p1){//t->expn比当前列表所有元素的指数都大,则上面的while循环会因为p2到达了尾节点,p1=NULL而跳出q = p2;return false;}
}
//输入m项的系数和指数,建立表示一元多项式的带有头节点的有序链表P
//利用尾插法
void createPolyn(polynomial &P, int m){//先建立一个带有头节点的空链表,即初始化P = (polynomial)malloc(sizeof(term));P->next = NULL;LinkList r = P;//r指针总是指向当前线性表的最后一个元素,即尾元素printf("输入系数,指数,如项2x^5则输入(2,5):\n");//不必按升幂输入for(int i = 0; i < m; i++){//依次输入m个非零项LinkList t = (LinkList)malloc(sizeof(term));t->next = NULL;LinkList q;scanf("%f,%d",&t->coef,&t->expn);if(!locateElem(P, t, q)){//当前链表中不存在该指数项,则插入,此时q为链表中第一个指数>t->expn的节点的前驱结点t->next = q->next;q->next = t;}else{//当前列表中已经存在有节点元素的指数与本次输入的项的指数相同,所以本次输入无效,应重新输入i--;}}
}
//打印多项式链表
void printPolynomial(polynomial P){LinkList q = P->next;printf("打印多项式的线性表:[");while(q){printf("(%.2f,%d)  ",q->coef, q->expn);q = q->next;}printf("]\n\n");
}
//多项式加法:Pa=Pa+Pb,利用2个多项式的节点构成“和多项式”
void addPolyn(polynomial &Pa, polynomial &Pb){LinkList qa = Pa->next;LinkList qb = Pb->next;LinkList qc = Pa;//pc总是指向"和多项式链表"的最后一个节点float sumOfCoef;while(qa&&qb){switch(cmp(qa, qb)){case 1:qc->next = qb;qc = qb;qb = qb->next;break;case 0://当前比较的两项的指数相同sumOfCoef = qa->coef + qb->coef;if(sumOfCoef != 0.0){//系数之和不为0,则修改qa所指节点的系数,同时释放gb所指节点LinkList s = qb;//s即将被free掉qa->coef = sumOfCoef;qc->next = qa;qc = qa;qa = qa->next;qb = qb->next;free(s);}else{//系数之和不为0,则从多项式链表A中删除qa所指节点,并free掉qa、qb所指节点LinkList s1 = qa;LinkList s2 = qb;qc->next = qa ->next;//qc的位置不变,qa、qb向后移动qa = qa->next;qb = qb->next;free(s1);free(s2);}break;case -1:qc->next = qa;qc = qa;qa = qa->next;break;}//end switch}//end whileqc->next = qa?qa:qb;//插入剩余段free(Pb);//释放Pb的头节点
}
//实例:Pa(x)=7+3x+9x^8+5x^17, 输入((7,0),(3,1),(9,8),(5,17))
//Pb(x)=8x+22x^7-9x^8,输入((8,1),(22,7),(-9,8))
//和多项式为Pa(x) = 7+11x+22x^7+5x^17,即最后应该输出((7,0),(11,1),(22,7),(5,17))
int main(){polynomial Pa;createPolyn(Pa, 4);//初始化并创建多项式链表PaprintPolynomial(Pa);polynomial Pb;createPolyn(Pb, 3);//初始化并创建多项式链表PaprintPolynomial(Pb);printf("执行多项式相加以后\n");addPolyn(Pa, Pb);printPolynomial(Pa);return 0;
}

本文中的代码可从这里下载:https://github.com/qingyujean/data-structure

数据结构(3)--线性表实现一元多项式加法相关推荐

  1. c++用模板实现稀疏多项式_用线性表实现一元多项式及相加运算

    " 本文主要讨论线性表在多项式计算中的应用,讨论内容涉及到一元n次多项式在计算机中的表示,及多项式相加运算." 01 在数学上,一个一元n次多项式可以按照升幂写成 Pn(x)= p ...

  2. 线性表实现一元多项式的表示及相加(C语言实现)【线性表】

    一元多项式的表示及相加 一元多项式抽象数据类型的动态链式表示 操作举例:构造多项式 一元多项式的表示及相加 符号多项式的表示及其操作是线性表处理的典型用例. 一个一元多项式 Pn(x) 可以表示为 : ...

  3. 线性表实现一元多项式操作

    数组存放: 不需要记录幂,下标就是. 比如1,2,3,5表示1+2x+3x^2+5x^3 有了思路,我们很容易定义结构 typedef struct node{float * coef;//系数数组i ...

  4. 数据结构(运用线性表实现函数的查找、删改、查询)

    运用线性表实现函数的查找.删改.查询 #include <iostream> #define MaxSize 100 using namespace std; typedef int EL ...

  5. 线性表实现多项式相加c语言,用线性表实现多个多项式相加

    今天开始想复习一下数据结构,就从线性表开始吧. 今天是用线性表实现多个多项式相加这个题目,自变量是x. 题目描述如下: 在数学上,一个一元多项式Pn(x)可按降幂写成:Pn(x) = pn x^n + ...

  6. [自制简单操作系统] 4、计时器(线性表实现优化中断)

    1.第一版:数组方式[09d] >_<" 在bootpack.h里面的timer.c的声明和结构体: 1 /* timer.c */ 2 #define MAX_TIMER 50 ...

  7. 【数据结构】顺序表实现超详解(保姆级教程)

    [数据结构] 目录 ​ 前言 顺序表 接口实现 各项功能 接口详解 顺序表初始化 顺序表释放 顺序表展示 顺序表容量检查 顺序表数据尾插 顺序表数据头插 顺序表数据前删 顺序表数据尾删 顺序表数据查找 ...

  8. 线性表实现顺序存储结构的完整代码(C语言)

    代码如下: #include<stdio.h> #include<stdlib.h> #include<string.h> #define MAXSIZE 20 # ...

  9. 利用线性表实现通讯录管理

    //实现通讯录的建立.增加.删除.修改.查询等功能 // 能够实现简单的菜单交互,即可以根据用户输入的命令,选择不同的操作. #include<iostream>  #include< ...

最新文章

  1. 洛谷模拟赛 部落冲突
  2. 大数据WEB阶段 shiro安全控制框架
  3. python画图数据的平均值怎么算的_Python气象数据处理与绘图(2):常用数据计算方法...
  4. SFTP是什么?与FTP之间有什么区别
  5. python代码少的作品_世界上有哪些代码量很少,但很牛逼很经典的算法或项目案例?...
  6. python中seaborn_python的seaborn模块
  7. 《软件定义数据中心:Windows Server SDDC技术与实践》——第1章 微软数据中心与SDDC漫谈1.1 微软数据中心建设之道...
  8. 管理系统中的计算机应用数据库系统,自考管理系统中的计算机应用重点: 数据库系统(1)...
  9. matlab 高级函数 —— circshift、squeeze
  10. springboot集成quartz
  11. 微信小程序 后端返回数据为字符串,转json方法
  12. CCF-CSP历年真题大全附题解(202209已更)
  13. 营销公众号该如何运营大纲
  14. 完全二叉树的权值——两种解法
  15. Teams App自定义
  16. 主流室内定位技术分析
  17. js截取图片 裁剪图片之cropper.js插件用法详解
  18. java课程(54G)2019全套学习视频免费分享
  19. 前端学习之路CSS基础学习二
  20. 利用三级结构进行蛋白质嵌入的自我监督预训练

热门文章

  1. 【毕业设计草计】安全
  2. 视频图像去重复 修改视频MD5
  3. 优选pp管、pph管、frpp管
  4. 计算机品牌调查表excel,如何用excel统计的调查问卷
  5. 哪种蓝牙耳机音质好又便宜?便宜又好用的耳机蓝牙耳机推荐
  6. 最大熵模型(MEM)
  7. 防火墙支持的日志格式
  8. 华为云大面积宕机的原因思考-谁是下一个背锅侠?
  9. Nvm,Nrm使用教程
  10. 杉岩:小天才手表背后的故事,超融合数据库最佳实践