您的位置:首页 > 其它

一元稀疏多项式加减法(自动排序降序版)

2012-11-20 22:25 411 查看
Thanks for Boss. Wang ~。~

 

算法描述及详解请见  
一元稀疏多项式(原版)——Chuck_0430

 

#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct Polynomial  //创建结构体
{
float coef;    //系数域
int expn;      //指数域
struct Polynomial *next;   //指针域
}*Polyn,Polynomial;               //Polyn为结点指针类型
void Insert(Polyn p,Polyn h)
{
if(p->coef==0) free(p);       //系数为0的话释放结点
else
{
Polyn q1, q2;
q1=h;
q2=h->next;
while(q2 && p->expn<q2->expn)   //当指数出现较小的情况时,存入且排序
{   //查找插入位置
q1=q2;
q2=q2->next;
}
if(q2 && p->expn==q2->expn)
{   //将指数相同相合并
q2->coef += p->coef;
free(p);
if(!(q2->coef))
{   //系数为0的话释放结点
q1->next=q2->next;
free(q2);
}
}
else
{   //指数为新时将结点插入
p->next=q2;
q1->next=p;
}
}
}
Polyn CreatePolyn(Polyn head,int m)
{   //建立一个头指针为head、项数为m的一元多项式
int i;
Polyn p;
p = head = (Polyn)malloc(sizeof(struct Polynomial)); //申请头节点空间,建立空表
head->next=NULL;
for(i=1; i<=m; i++)
{
p=(Polyn)malloc(sizeof(struct Polynomial));//建立新结点以接收数据
printf("请输入第%d项的系数与指数:",i);
scanf("%f %d",&p->coef,&p->expn);
Insert(p,head);   //调用Insert函数插入结点
}
return head;
}
void DestroyPolyn(Polyn p)
{   //销毁多项式p
Polyn q1,q2;
q1=p->next;
q2=q1->next;
while(q1->next != NULL)
{
free(q1);
q1=q2;
q2=q2->next;  //指针后移
}
}
void PrintPolyn(Polyn P)
{
Polyn q=P->next;
int flag=1;   //项数计数器
if(!q)
{   //若多项式为空,输出0
putchar('0');
printf("\n");
return;
}
while (q)
{
if(q->coef>0 && flag!=1)
putchar('+'); //系数大于0且不是第一项
if(q->coef!=1 && q->coef!=-1)
{   //系数非1或-1的普通情况
printf("%g",q->coef);
if(q->expn==1) putchar('X');
else
if(q->expn)
printf("X^%d",q->expn);
}
else
{
if(q->coef==1)  //系数为1的情况
{
if(!q->expn)  //指数不为0时
putchar('1');
else if(q->expn==1) //指数为1时
putchar('X');
else
printf("X^%d",q->expn);
}
if(q->coef==-1)  //项数为负项即系数为负数时
{
if(!q->expn)
printf("-1");
else if(q->expn==1)
printf("-X");
else
printf("-X^%d",q->expn);
}
}
q=q->next;
flag++; //计数器加1
}
printf("\n");
}
int compare(Polyn a,Polyn b)
{
if(a&&b)  //两链表都不是空表时
{
if(!b||a->expn>b->expn) return 1;
else if(!a||a->expn<b->expn) return -1;
else return 0;
}
else if(!a&&b) return -1;  //a多项式已空,但b多项式非空
else return 1;        //b多项式已空,但a多项式非空
}
Polyn AddPolyn(Polyn pa,Polyn pb)
{   //求解并建立多项式a+b,返回其头指针
Polyn headc, hc, qc;
Polyn qa=pa->next;
Polyn qb=pb->next;
hc=(Polyn)malloc(sizeof(struct Polynomial));   //建立头结点,置为空表
hc->next=NULL;
headc=hc;
while(qa||qb)
{
qc=(Polyn)malloc(sizeof(struct Polynomial));
switch(compare(qa,qb))  //进行排序
{
case 1:  //a链表对应项指数较大时
{
qc->coef=qa->coef;
qc->expn=qa->expn;
qa=qa->next;
break;
}
case 0:  //a,b链表对应项指数相等时
{
qc->coef=qa->coef+qb->coef;
qc->expn=qa->expn;
qa=qa->next;
qb=qb->next;
break;
}
case -1:   //a链表对应项指数较小时
{
qc->coef=qb->coef;
qc->expn=qb->expn;
qb=qb->next;
break;
}
}
if(qc->coef!=0)  //若加和之后的系数不为0的话
{
qc->next=hc->next;
hc->next=qc;
hc=qc;
}
else free(qc);//当相加系数为0时,释放该结点
}
return headc;
}
Polyn SubtractPolyn(Polyn pa,Polyn pb)
{   //求解并建立多项式a+b,返回其头指针
Polyn h=pb;
Polyn p=pb->next;
Polyn pd;
while(p)
{           //将pb的系数取反
p->coef*=-1;
p=p->next;
}
pd=AddPolyn(pa,h);  //剩余的都与加法中的步骤相同,直接调用
for(p=h->next;p;p=p->next)    //恢复pb的系数
p->coef*=-1;
return pd;
}
int main()
{
int m,n,flag=0;
Polyn pa=0,pb=0,pc,pd;   //定义各式的头指针,pa与pb在使用前付初值NULL
printf("请输入a的项数:");
scanf("%d",&m);
pa=CreatePolyn(pa,m);   //建立多项式a
printf("请输入b的项数:");
scanf("%d",&n);
pb=CreatePolyn(pb,n);   //建立多项式b
/*输出菜单,输入1就将a,b链表降序并输出
输入2就执行加法运算并降序输出
输入3就执行减法运算并降序输出
输入4就退出。*/
printf("**********************************************\n");
printf("操作提示:\n\t1.输出多项式a和b\n\t2.建立多项式a+b\n\t3.建立多项式a-b\n");
printf("\t4.退出\n**********************************************\n");
for(;;flag=0)
{
printf("执行操作:");
scanf("%d",&flag);
if(flag==1)   //将两链表降序输出
{
printf("多项式a:");
PrintPolyn(pa);
printf("多项式b:");
PrintPolyn(pb);
continue;
}
if(flag==2)   //执行加法操作并降序输出
{
pc=AddPolyn(pa,pb);
printf("多项式a+b:");
PrintPolyn(pc);
DestroyPolyn(pc);
continue;
}
if(flag==3)   //执行减法操作并降序输出
{
pd=SubtractPolyn(pa,pb);
printf("多项式a-b:");
PrintPolyn(pd);
DestroyPolyn(pd);
continue;
}
if(flag==4) break;   //运行错误或者编译输入错误等等
if(flag<1||flag>4)
{
printf("Error!!!\n");
continue;
}
}
DestroyPolyn(pa);
DestroyPolyn(pb);    //清空链表
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: