一元多项式的表示与运算——课程设计(无序输入 有序输出)
目录
- 一元多项式的表示与运算——课程设计(无序输入 有序输出)
- 一.例题:(输入无序,指数升序排列的一元多项式)
- 1. 链表结点定义
- 2. 创建单链表存放一元多项式(将无序的输入有序存放于链表)
- 3. 输出一元多项式
- 4. 一元多项式求值
- 5. 删除一元多项式中的指定项
- 6. 实现两个一元多项式相加 ha = ha + hb
- 二.例题:(有序)指数升序排列输出一元多项式
- 1. 链表结点定义
- 2. 创建单链表存放一元多项式(按照指数升序排列)
- 3. 按升序输出一元多项式
- 4. 计算一元多项式的值
- 5. 实现两个一元多项式相加 ha = ha + hb
∙ 主要内容:用线性表表示一元多项式。实现一元多项式的相加、求导、求值、相减等运算
相加算法实现:首先确定表示一元多项式的线性表的存储方式----顺序存储结构,链式存储结构均可;
两种存储方式:顺序存储结构和链式存储结构(本文采用链式存储方式解题)
- 一元多项式的指数很高且相邻的指数相差很大时,宜只存放系数非零项的系数和相应的指数,否则浪费存储,且系数非零项仍按指数升序排列方便运算实现。(存储中根据系数的稀疏性来选择)
- 对于次数低的,方便多项式之间的运算,可采用按项顺序存储的形式。
一.例题:(输入无序,指数升序排列的一元多项式)
【问题描述】读入一元多项式中每一项的系数和指数,建立单链表存放输入的一元多项式,写出遍历单链表输出所存放的一元多项式,一元多项式相加,求一元多项式的值,删除一元多项式中指定项等相关操作
【输入形式】x的值,2个一元多项式各项(顺序随意),要删除相加后多项式的指数项
【样例输入1】
2 -1 0 8 3 10 8 2 20 0 0 1 0 5 3 6 2 2 20 0 0 8
【样例说明1】 输入: 第1行的2是一元多项式x的值 第2行和第3行是两个一元多项式每一项的系数和指数,不要求有序输入,以0 0结束
第4行是删除的相加后多项式的指数项
输出 第1、2、3行,参照例子 第4行为删除相加后指数项之后的多项式.
【样例输入2】
2 1 2 3 5 4 3 0 0 2 0 -3 5 3 3 2 1 0 0 3
1. 链表结点定义
/* 链表结点定义 */ typedef struct LNode{ int exp, coef; //coef为指数, exp为系数 struct LNode *next; }LNode, *LinkList;
2. 创建单链表存放一元多项式(将无序的输入有序存放于链表)
/* 创建单链表存放一元多项式*/ void CreateList(LinkList &L) { L=(LinkList)malloc(sizeof(LNode)); L->next = NULL; LinkList p; LinkList pre=L;// LinkList s=L;// 尾插法的尾指针 L->coef = 0.0;//先初始化一下 L->exp = 0; //一直输入 检测到 输入0 0 的时候截至 while(true){ p=(LinkList)malloc(sizeof(LNode)); p->next=NULL; if(p==NULL) return;//是否开辟成功 scanf("%d",&p->coef); scanf("%d",&p->exp); if(!p->exp&&!p->coef){ free(p); //如果输入有误 就把多开辟的空间释放掉 return; } if(p->exp>=s->exp){//输入正序的话就尾插 s->next = p; s=p; } else{//输入比上一个小 说明输入无序 插入 while(pre->next){ pre=pre->next;//从头向后找 插入的位置 if(pre->next->exp>p->exp && pre->exp <= p->exp){ //找到插入的位置 p->next = pre->next;//插入 pre->next=p; pre = L;//重置pre的指向位置 以便下一次找位置 break;//插入完成 退出循环 } } } } }
3. 输出一元多项式
//遍历单链表,格式化输出一元多项式的每一项 void Display(LinkList L) { LinkList p = L->next; int First_Term = 1; //表示当前处理的项是否是多项式的第一项 第一项前面不需要额外正负号 while (p != NULL) { if (p->exp) { if (!First_Term && p->coef > 0) { //整数加上+号 printf("+"); } printf("%dx^%d", p->coef, p->exp); } else { //指数为零 直接打印 printf("%d", p->coef); } First_Term = 0; //修改标签 p = p->next; } }
4. 一元多项式求值
/* 一元多项式求值 */ double Value(LinkList L, int x) { LinkList p=L->next; double function_sum=0.0; while(p!=NULL){ function_sum += p->coef*pow(x,p->exp); p=p->next; } return function_sum; }/* 一元多项式求值 */
5. 删除一元多项式中的指定项
/*删除一元多项式中的指定项 */ void DeleteElem(LinkList &L, int e) { //在这里插入你的代码 LinkList p=L->next;//线性表的第一个数据元素 //p在前面 探路 LinkList q=L;// q指向 p的前驱结点地址 while(p!=NULL){ if(p->exp==e){//发现指定指数项 q->next=p->next;//删除该项 free(p); return; } else{ //未发现该指数项 两指针后移 继续探寻 q=p; p=p->next; } } }//DeleteElem
6. 实现两个一元多项式相加 ha = ha + hb
//ha = ha + hb void AddPoly(LinkList ha,LinkList hb) { LinkList pa = ha->next;//探路 LinkList pb = hb->next;//探路 LinkList p = ha;// p指向 pa的前继结点 while(pa&&pb){ if(pa->exp
exp){ //情况一:当ha中该项的指数小时 指针p 和 pa 直接向后移动一位 p = pa;//后移 pa=pa->next;//后移 } else if(pa->exp>pb->exp){ //情况二:当ha中该项的指数大时 需要将hb中该节点 连接进来 //接入: 指针p 的后继指向pb pb的后继指向pa //后移: p 、pb均向后移动一位 hb->next=pb->next;//ha 拿走该pb指向的这个结点 pb->next=pa;//接入: 指针p 的后继指向pb pb的后继指向pa p->next=pb; p=pb;//后移: p 、pb均向后移动一位 pb=hb->next; } else{ //情况三:相等的时候 需要求和 pa->coef +=pb->coef;//求和:放入ha中 hb->next=pb->next;//该pb指向的节点直接删 他的系数已经被ha加上了 free(pb);//释放空间 pb=hb->next;//更新pb的指向 if(pa->coef){ //不为零时 正常后移 p = pa; } else{//删除相加后 系数为0 的项 //系数为零时 // 节省储存空间 p->next = pa->next; free(pa);//这个释放的原理 要搞清楚 //更新pa的指向 } pa=p->next;//更新pa的指向 pa } } p->next = pa?pa:pb;//接入剩余的结点 free(hb);//释放空间 } 二.例题:(有序)指数升序排列输出一元多项式
从键盘读入一元多项式中每一项的系数和指数,请编写算法实现(类C语言算法描述,不是完整程序代码):
(1)建立带表头结点的单链表存放一元多项式(按照指数升序排列); void CreatePoly(LinkList &pa)
(2)输出一元多项式的所有数据元素(按照指数升序输出每一系数非0项的系数和指数); void Display(LinkList pa)
(3)输入自变量的值,计算一元多项式的值; int Evaluation(LinkList pa, int
x),pa为头结点,x为自变量,返回值为一元多项式的值 (4)输入两个一元多项式,求一元多项式的和多项式(不是求值)。 void
AddPoly(LinkList ha,LinkList hb),结果放入ha链表
1. 链表结点定义
typedef struct Node{ float coef_num;//系数的值 int expn_num;//指数的值 struct Node *next; }Term,*LinkList; //使用链表
2. 创建单链表存放一元多项式(按照指数升序排列)
//(1)建立带表头结点的单链表存放一元多项式(按照指数升序排列); //循环截至条件 按个数输入 void CreatePoly(LinkList &pa) { int m; cout<<"请输入 一元多项式的项数"<
>m; pa=(LinkList)malloc(sizeof(Node)); pa->next = NULL; LinkList p; LinkList s=pa; pa->coef_num = 0.0;; pa->expn_num = 0; // 输入到指定 个数停止 for(int i = 0; i < m; i++){ p=(LinkList)malloc(sizeof(Node)); p->next=NULL; if(p==NULL) return; cin>>p->coef_num; cin>>p->expn_num; //尾插法 s->next = p; s=p; } } void CreatePoly1(LinkList &pa) { cout<<"请输入 一元多项式的系数(系数不为零) 和 指数(输入0 0时停止)"< next = NULL; LinkList p; LinkList s=pa; pa->coef_num = 0.0; pa->expn_num = 0; //一直输入 检测到 输入0 0 的时候截至 while(true){ p=(LinkList)malloc(sizeof(Node)); p->next=NULL; if(p==NULL) return; cin>>p->coef_num; cin>>p->expn_num; if(!p->expn_num&&!p->coef_num){ free(p); return; } //尾插法 s->next = p; s=p; } } 3. 按升序输出一元多项式
//(2)输出一元多项式的所有数据元素(按照指数升序输出每一系数非0项的系数和指数); void Display(LinkList pa) { LinkList p=pa->next; while(p!=NULL){ cout<< p->coef_num<<" "<
expn_num< next; } } 4. 计算一元多项式的值
//输入自变量的值,计算一元多项式的值; float Evaluation(LinkList pa, int x){//pa为头结点,x为自变量,返回值为一元多项式的值 LinkList p=pa->next; float function_sum=0.0; while(p!=NULL){ function_sum += p->coef_num*pow(x,p->expn_num); p=p->next; } return function_sum; }
5. 实现两个一元多项式相加 ha = ha + hb
void AddPoly1(LinkList ha, LinkList hb){ LinkList pa = ha->next;//探路 LinkList pb = hb->next;//探路 LinkList p = ha;// pa的前继结点 // while(pa&&pb) if(pa->expn_num
expn_num){ //情况一:当ha中该项的指数小时 指针p 和 pa 直接向后移动一位 p=pa; pa=pa->next; } else if(pa->expn_num == pb->expn_num){ //情况二:相等的时候 需要求和 pa->coef_num += pb->coef_num;//求和:放入ha中 hb->next=pb->next;//该pb指向的节点直接删 他的系数已经被ha加上了 free(pb); pb=hb->next; if(!pa->coef_num){ //判断加和后系数是否为零 //系数为零的情况 删除pa指向的这个结点 p->next=pa->next; free(pa);//pa指向的释放了这个地址 pa=p->next; } else{ //如果不为零 正常后移 p=pa; pa=pa->next; } } else{ //情况三:当ha中该项的指数大时 需要将hb中该节点 连接进来 //接入: 指针p 的后继指向pb pb的后继指向pa //后移: p 、pb均向后移动一位 hb->next=pb->next;//ha 拿走该pb指向的这个结点 pb->next=pa;//接入: 指针p 的后继指向pb pb的后继指向pa p->next=pb; p=pb;//后移: p 、pb均向后移动一位 pb=hb->next; } if(pb) p->next=pb;//接入剩余的结点 free(hb); }