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

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;
}


 

你可能感兴趣的:(一元稀疏多项式加减法(自动排序降序版))