一元多项式的运算(用C++语言链表实现)
需要基于线性表的基本操作实现一元多项式的加法,需要用有序链表实现。
#include <stdio.h> #include <malloc.h> #include <stdlib.h> //定义多项式链表的'结点'存储结构,每一个结点对应稀疏多项式中的一项 typedef struct Node { //数据域 float coef;//定义多项式的系数 int expn;//定义多项式的指数 //指针域 struct Node * pNext; }NODE,*PNODE;//NODE 等价于struct Node ,PNODE等价于struct Node* //函数声明 PNODE create_list();//创建一个多项式链表 void traverse_list(PNODE pHead);//遍历输出多项式链表中的所有元素 void Destroy(PNODE pHead);//销毁链表 int length_list(PNODE pHead);//返回多项式链表的长度 void sort_list(PNODE pHead);//对多项式链表中的元素进行排序,按降序排序 void Ult(PNODE pHead);//Ult即unit like terms 合并同类项 void Der(PNODE pHead);//Derivative求导; PNODE ADD(PNODE pHeadA,PNODE pHeadB);//计算 pHeadA + pHeadB,并返回保存结果的链表的地址 PNODE SUB(PNODE pHeadA,PNODE pHeadB);//计算 pHeadA - pHeadB,并返回保存结果的链表的地址 PNODE MUL(PNODE pHeadA,PNODE pHeadB);//计算 pHeadA * pHeadB,并返回保存结果的链表的地址 int main(void) { PNODE pHeadA = NULL;//等价于 struct Node *pHeadA=NULL; PNODE pHeadB = NULL;//等价于 struct Node *pHeadB=NULL; PNODE pHeadC = NULL;//等价于 struct Node *pHeadB=NULL; int len=0; int choice = 0; while(choice!=5)//只要不选择5退出,就让程序一直执行 { choice = 0; printf("你想要实现哪些功能: \n"); printf(" 1.求导(对输入的一个多项式求导,并输出结果)\n"); printf(" 2.多项式相加(计算 A + B 并输出结果)\n"); printf(" 3.多项式相减(计算 A - B 并输出结果)\n"); printf(" 4.多项式相乘(计算 A * B 并输出结果)\n"); printf(" 5.退出整个程序\n"); while( (choice<1)||(choice>5) ) { printf("请输入你的选择:\n"); scanf("%d",&choice); } switch(choice) { case 1: pHeadA = create_list(); sort_list(pHeadA); Ult(pHeadA); traverse_list(pHeadA); Der(pHeadA); printf(" A' = "); traverse_list(pHeadA); Destroy(pHeadA); break; case 2: //创建A pHeadA = create_list(); sort_list(pHeadA); Ult(pHeadA); traverse_list(pHeadA); //创建B pHeadB = create_list(); sort_list(pHeadB); Ult(pHeadB); traverse_list(pHeadB); //创建A+B pHeadC = ADD(pHeadA,pHeadB); sort_list(pHeadC); Ult(pHeadC); printf("A + B = "); traverse_list(pHeadC); //销毁链表,释放内存 Destroy(pHeadA); Destroy(pHeadB); Destroy(pHeadC); break; case 3: //创建A pHeadA = create_list(); sort_list(pHeadA); Ult(pHeadA); traverse_list(pHeadA); //创建B pHeadB = create_list(); sort_list(pHeadB); Ult(pHeadB); traverse_list(pHeadB); //创建A-B pHeadC = SUB(pHeadA,pHeadB); sort_list(pHeadC); Ult(pHeadC); printf("A - B = "); traverse_list(pHeadC); //销毁链表,释放内存 Destroy(pHeadA); Destroy(pHeadB); Destroy(pHeadC); break; case 4: //创建A pHeadA = create_list(); sort_list(pHeadA); Ult(pHeadA); traverse_list(pHeadA); //创建B pHeadB = create_list(); sort_list(pHeadB); Ult(pHeadB); traverse_list(pHeadB); //创建A*B pHeadC = MUL(pHeadA,pHeadB); sort_list(pHeadC); Ult(pHeadC); printf("A * B = "); traverse_list(pHeadC); //销毁链表,释放内存 Destroy(pHeadA); Destroy(pHeadB); Destroy(pHeadC); break; default:; } printf("按回车继续!\n"); char c = 'q'; c = getchar(); c = getchar(); if(c == '\n') system("cls"); //清屏 } return 0; } PNODE create_list() { int len;//用来存放多项式的项数 int i; //用于循环的变量 float val_coef;//临时存放用户输入的多项式的系数 int val_expn;//临时存放用户输入的多项式的指数 //分配了一个不存放有效数据的头节点 PNODE pHead = (PNODE)malloc(sizeof(NODE)); if(NULL == pHead) { printf("分配失败!程序终止!"); exit(-1); } PNODE pTail = pHead;//定义了一个尾指针,该指针永远指向链表的最后一个结点 pTail->pNext = NULL;//最后一个结点的指针域为空 printf("请输入要生成的多项式的项数:len="); scanf("%d",&len); for(i=0;i<len;i++) { printf("请输入第%d项的系数和指数:",i+1); scanf("%f %d",&val_coef,&val_expn); PNODE pNew = (PNODE)malloc(sizeof(NODE));//创建一个新结点pNew if(NULL == pNew) { printf("动态内存分配失败!程序终止!"); exit(-1); } pNew->coef = val_coef;//将用户输入的系数到新节点的系数变量 pNew->expn = val_expn;//将用户输入的指数到新节点的指数变量 pTail->pNext= pNew;//将新节点挂到尾结点后面,即将新节点的地址赋给尾结点指针域 pNew->pNext= NULL;//新结点成为了最后一个结点,所以指针域为空 pTail = pNew;//将尾指针指向新结点 } return pHead;//返回创建的链表的头节点的地址 } void traverse_list(PNODE pHead) { PNODE p = pHead->pNext;//定义一个指针,让其指向第一个有效结点(首结点) if(NULL == p) { printf("你要输出的多项式不存在!\n"); exit(-1); } while(NULL != p)//只要p指针指向的结点不为空,就将这个结点的数据输出 { //如果系数为0,该项不必输出,直接跳过到下一项 if(0 == p->coef) { p = p->pNext; continue; } //系数非0,输出该项的内容 else { //如果该项的系数不等于1 if(1 != p->coef) { //如果该项的指数为0,不用再输出变量x和指数 if(0 == p->expn) printf("%0.1f",p->coef); //如果该项的指数为1,不用再输出指数 else if(1 == p->expn) { if(-1 == p->coef) printf("-X"); else printf("%0.1fX",p->coef); } else { { if(-1 == p->coef) printf("-X^%d",p->expn); else printf("%0.1fX^%d",p->coef,p->expn); } } } //如果系数等于1 else { //如果该项的指数为0,不用再输出变量x和指数 if(0 == p->expn) printf("%0.1f",p->coef); //如果该项的指数为1,不用再输出指数 else if(1 == p->expn) printf("X"); else printf("X^%d",p->expn); } //如果有下一项,并且下一项的系数不是负数,则需要输出'+' 连接 if( (NULL!=p->pNext)&&(0 < p->pNext->coef) ) printf("+"); p = p->pNext; } } printf("\n"); return; } /*销毁链表*/ void Destroy(PNODE pHead) { PNODE q=NULL; if(NULL == pHead->pNext) { printf("空链表无需销毁!\n"); exit(-1); } else { for(q=pHead;q!=NULL;q=pHead) { pHead = pHead->pNext; free(q); } } } int length_list(PNODE pHead) { PNODE p = pHead->pNext; int len = 0; while(NULL != p) { ++len; p = p->pNext; } return len; } void sort_list(PNODE pHead) { int i, j;//i,j变量用于循环 PNODE temp=(PNODE)malloc(sizeof(NODE));//temp变量将用于临时存放一个多项式 int len = length_list(pHead);//len保存多项式项数 PNODE p, q;//p相当于i,q相当于j,该排序算法类似于数组的选择排序 for(i=0,p=pHead->pNext;i<len-1;++i,p=p->pNext) { for(j=i+1,q=p->pNext; j<len; ++j,q=q->pNext) { if(p->expn < q->expn)//类似于数组中的a[i] < a[j] { temp->coef = p->coef;//类似于数组中的 t=a[i] temp->expn = p->expn; p->coef = q->coef;//类似于数组中的 a[i]=a[j] p->expn = q->expn; q->coef = temp->coef;//类似于数组中的 a[j]=t; q->expn = temp->expn; } } } free(temp); return; } void Ult(PNODE pHead) { PNODE p = pHead->pNext;//定义指针p,并让其指向首结点 if(NULL == p) { printf("要进行合并的多项式不存在!\n"); exit(-1); } PNODE q = p->pNext;// 定义指针q,并让其指向p的后继结点 PNODE temp = NULL;//定义一个临时指针,用于合并同类项时,删除节点 sort_list(pHead); while(NULL != q) { if(p->expn == q->expn) { p->coef = p->coef + q->coef; temp = q; p->pNext = q->pNext; p = q->pNext; free(temp); if(NULL == p) break; else q = p->pNext; } else { p = q; q = p->pNext; } } } void Der(PNODE pHead) { PNODE p = pHead->pNext;//定义p指针指向首结点 if(NULL == p) { printf("要求导的多项式不存在!\n"); exit(-1); } while(NULL!=p) { p->coef = p->coef * p->expn; --p->expn; p = p->pNext; } } PNODE ADD(PNODE pHeadA,PNODE pHeadB) { if(NULL == pHeadA->pNext) { printf("错误!没有多项式A"); exit(-1); } if(NULL == pHeadB->pNext) { printf("错误!没有多项式B"); exit(-1); } PNODE p, q;//p指针将用来指向项数较多的多项式的第一项,q指针将用来指向项数较少的多项式的第一项 , PNODE pHeadC = (PNODE)malloc(sizeof(NODE));//pHeadC指向头节点 if(NULL == pHeadC) { printf("分配失败!程序终止!"); exit(-1); } PNODE pTail = pHeadC;//定义了一个尾指针,该指针永远指向链表的最后一个结点 pTail->pNext = NULL;//最后一个结点的指针域为空 if(length_list(pHeadA)>length_list(pHeadB)) { p = pHeadA->pNext; q = pHeadB->pNext; } else { p = pHeadB->pNext; q = pHeadA->pNext; } for(;;)//只要两个指针指向的多项式不为空,就一直循环,计算 { //分三种情况,p指向的项的指数大于q 指向的项的指数,还有等于,小于 //由于两个多项式都是按指数降序排序,所以:大于时 p指向的项可以直接存入pHeadc,等于时相加后再存入pHeadC,小于时 q指向的项可以直接存入pHeadc if(NULL==p&&NULL==q)break; PNODE pNew = (PNODE)malloc(sizeof(NODE));//创建一个新结点pNew if(NULL == pNew) { printf("动态内存分配失败!程序终止!"); exit(-1); } if( (NULL != p)&&(NULL != q) ) { if(p->expn > q->expn) { pNew->coef = p->coef; pNew->expn = p->expn; p = p->pNext; } else if(p->expn == q->expn) { pNew->coef = p->coef + q->coef; pNew->expn = p->expn; p = p->pNext; q = q->pNext; } else if(p->expn < q->expn) { pNew->coef = q->coef; pNew->expn = q->expn; q = q->pNext; } } else if( (NULL==q)&&(NULL != p) ) { pNew->coef = p->coef; pNew->expn = p->expn; p = p->pNext; } else if( (NULL!=q)&&(NULL == p)) { pNew->coef = q->coef; pNew->expn = q->expn; q = q->pNext; } pTail->pNext= pNew;//将新节点挂到尾结点后面,即将新节点的地址赋给尾结点指针域 pNew->pNext= NULL;//新结点成为了最后一个结点,所以指针域为空 pTail = pNew;//将尾指针指向新结点 } return pHeadC; } PNODE SUB(PNODE pHeadA,PNODE pHeadB) { if(NULL == pHeadA->pNext) { printf("错误!没有多项式A"); exit(-1); } if(NULL == pHeadB->pNext) { printf("错误!没有多项式B"); exit(-1); } PNODE p = pHeadB->pNext;//定义一个指针,让其指向第一个有效结点(首结点) PNODE pHeadC = (PNODE)malloc(sizeof(NODE));//pHeadC指向头节点 PNODE pHeadtemp = (PNODE)malloc(sizeof(NODE));//pHeadtemp用于保存-B if(NULL == pHeadtemp) { printf("分配失败!程序终止!"); exit(-1); } PNODE pTail = pHeadtemp;//定义了一个尾指针,该指针永远指向链表的最后一个结点 pTail->pNext = NULL;//最后一个结点的指针域为空 while(NULL != p) { PNODE pNew = (PNODE)malloc(sizeof(NODE));//创建一个新结点pNew if(NULL == pNew) { printf("动态内存分配失败!程序终止!"); exit(-1); } pNew->coef = -1*p->coef; pNew->expn = p->expn; p = p->pNext; pTail->pNext= pNew;//将新节点挂到尾结点后面,即将新节点的地址赋给尾结点指针域 pNew->pNext= NULL;//新结点成为了最后一个结点,所以指针域为空 pTail = pNew;//将尾指针指向新结点 } pHeadC = ADD(pHeadA,pHeadtemp); return pHeadC; } PNODE MUL(PNODE pHeadA,PNODE pHeadB) { if(NULL == pHeadA->pNext) { printf("错误!没有多项式A"); exit(-1); } if(NULL == pHeadB->pNext) { printf("错误!没有多项式B"); exit(-1); } PNODE p=NULL, q=pHeadB->pNext;//p指针将用来指向多项式A,q指针将用来指向多项式B PNODE pHeadC = (PNODE)malloc(sizeof(NODE));//pHeadC指向头节点 if(NULL == pHeadC) { printf("分配失败!程序终止!"); exit(-1); } PNODE pTail = pHeadC;//定义了一个尾指针,该指针永远指向链表的最后一个结点 pTail->pNext = NULL;//最后一个结点的指针域为空 for(p=pHeadA->pNext;NULL!=p;p=p->pNext) { for(q=pHeadB->pNext;NULL!=q;q=q->pNext) { PNODE pNew = (PNODE)malloc(sizeof(NODE));//创建一个新结点pNew if(NULL == pNew) { printf("动态内存分配失败!程序终止!"); exit(-1); } pNew->coef = p->coef *q->coef; pNew->expn = p->expn + q->expn; pTail->pNext= pNew;//将新节点挂到尾结点后面,即将新节点的地址赋给尾结点指针域 pNew->pNext= NULL;//新结点成为了最后一个结点,所以指针域为空 pTail = pNew;//将尾指针指向新结点 } } return pHeadC; }