02-线性结构2 一元多项式的乘法与加法运算 C

链表都不知道咋写了,感觉写这个重点在于自己复习了一下单链表。
其实写这个用了好久,遇到问题就死磕,不过收获还是蛮大的。

碎碎念:

其实写出来能运行之后调试花了很久,注意设置的四个测试点数据,每一个自己都举一个例子,就会出来了:
在这里插入图片描述
其实我有一次测试第三个和第四个都出现了段错误,但是试了例子:
0
1 2 1
解决第四个之后第三个也可以得到正确答案了,所以不需要拘泥于顺序
代码我会有注释,俗话说代码不加注释***,以便以后也可以看懂

一些具体的思路可以看浙大的数据结构mooc

有更好想法的小伙伴希望可以交流啊

一些思路:

乘法我是用加法实现的,例如:
(1+x) * ( 2x^2+x)
先初始化一个p指向NULL
p = 1 * 2x^2
p = p + 1 * x
p = p + x * 2x^2
p = p + x * x
最后就得到结果了

代码:

#include<stdio.h>
#include<stdlib.h>

typedef struct Node{
    int coef;       //系数
    int expon;      //指数
    struct Node *link;     //指向下一个节点的指针
}PolyNode;

typedef PolyNode *PtrToNode;	//指向节点的指针
typedef PolyNode *Polynomial;		//多项式

//增加一个尾节点
void Attach(int c, int e, PtrToNode *pRear);        //第三个参数传入的应该是节点指针的地址
//从标准输入中获得多项式
Polynomial GetPoly();
//输出
void DisplayPoly(Polynomial p);
//多项式加法
Polynomial PolyAdd(Polynomial p1, Polynomial p2);
//多项式乘法
Polynomial PolyMulti(Polynomial p1,Polynomial p2);
//销毁存储多项式的链表空间
void DestroyList(Polynomial p);

int main()
{
    Polynomial p1 = GetPoly();
    Polynomial p2 = GetPoly();
    Polynomial pm = PolyMulti(p1, p2);
    DisplayPoly(pm);
    putchar('\n');
    Polynomial pa = PolyAdd(p1, p2);
    DisplayPoly(pa);

    DestroyList(p1);
    DestroyList(p2);
    DestroyList(pm);
    DestroyList(pa);

    return 0;
}

Polynomial GetPoly(){
    int n;
    scanf("%d",&n);
    //先申请头节点,最后释放,易于插入操作
    PolyNode *front, *rear, *temp;  //三个标识符都要带*,注意temp
    rear = (PolyNode *)malloc(sizeof (PolyNode));
    front = rear;
    for(int i = 0; i < n; i ++){
        rear->link = (PolyNode *)malloc(sizeof(PolyNode));
        rear = rear->link;
        scanf("%d",&(rear->coef));
        scanf("%d",&(rear->expon));
    }
    rear->link = NULL;
    temp = front;
    front = front->link;		//front指向第一个存储多项式的节点
    free(temp);		//释放头节点
    return front;
}

void DisplayPoly(Polynomial p){
    if(p == NULL){
        printf("0 0");
        return;
    }
    else
        printf("%d %d",p->coef,p->expon);
    p = p->link;
    for(; p; p = p->link)
        printf(" %d %d",p->coef,p->expon);
}

void Attach(int c, int e, PtrToNode *pRear){
	//初始化节点
    PolyNode *p = (PolyNode *)malloc(sizeof(PolyNode));
    p->coef = c;
    p->expon = e;
    p->link = NULL;
    
    //插入尾部
    (*pRear)->link = p;
    //移动尾节点
    *pRear = p;
}

Polynomial PolyAdd(Polynomial p1, Polynomial p2){
    PolyNode *front, *rear, *temp;
    int sum;
    rear = (PolyNode *)malloc(sizeof(PolyNode));
    front = rear;
    while(p1 && p2){
        if(p1->expon > p2->expon){		//如果p1节点的指数大,先连到尾节点后面
            Attach(p1->coef,p1->expon,&rear);
            p1 = p1->link;
        }else if(p1->expon < p2->expon){		
            Attach(p2->coef, p2->expon,&rear);
            p2 = p2->link;
        }else{								//如果指数相同
            sum = p1->coef + p2->coef;		//系数相加
            if(sum)
                Attach(sum, p1->expon, &rear);
            p1 = p1->link;
            p2 = p2->link;
        }
    }
    
	//将剩下的节点插入尾部
    for(; p1; p1 = p1->link)
        Attach(p1->coef, p1->expon, &rear);
    for(; p2; p2 = p2->link)
        Attach(p2->coef, p2->expon, &rear);
    rear->link = NULL;      //p1,p2都为空时需要
    temp = front;
    front = front->link;
    free(temp);
    return front;
}


Polynomial PolyMulti(Polynomial p1,Polynomial p2){
    Polynomial p = NULL;
    Polynomial t1;
    Polynomial t2;
    for(t1 = p1; t1; t1 = t1->link){
        PtrToNode front, rear, temp;
        rear = (PolyNode *)malloc(sizeof(PolyNode));
        front = rear;
        for(t2 = p2; t2; t2 = t2->link)
            Attach(t1->coef * t2->coef,t1->expon + t2->expon,&rear);
        rear->link = NULL;
        temp = p;
        p = PolyAdd(p,front->link);
        DestroyList(temp);      //记得释放中间申请的内存
        free(front);
    }
    return p;
}

void DestroyList(Polynomial p){
    PtrToNode temp;
    while(p){		//p不为NULL
        temp = p;
        p = p->link;
        free(temp);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值