链表实现多项式的加法和乘法

poly.h

#ifndef POLYNOMIALCOMPUTE_POLY_H
#define POLYNOMIALCOMPUTE_POLY_H

struct PolyNode;
typedef struct PolyNode *Polynomial;

void Attach(int c, int e, Polynomial *pRear);
Polynomial PolyAdd(Polynomial P1, Polynomial P2);
Polynomial PolyMult(Polynomial P1, Polynomial P2);
Polynomial ReadPoly();
void PrintPoly(Polynomial P);

#endif //POLYNOMIALCOMPUTE_POLY_H

poly.c

#include "poly.h"
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>

struct PolyNode {
    Polynomial link; // 指向下一个节点的位置
    int expon; // 指数,英文是 exponent
    int coef; // 系数,英文是 coefficient
};

// 新增一个节点
void Attach(int c, int e, Polynomial *pRear)
{
    Polynomial P;

    P = (Polynomial)malloc(sizeof(struct PolyNode)); // 分配空间
    P->coef = c; // 对新节点赋值
    P->expon = e;
    P->link = NULL;
    (*pRear)->link = P; // 尾节点指向P
    *pRear = P; // 修改 pRear 值
}

int Compare(int Lhs, int Rhs)
{
    return Lhs - Rhs;
}

// 加法操作
Polynomial PolyAdd(Polynomial P1, Polynomial P2)
{
    Polynomial front, rear, temp;
    int sum;
    rear = (Polynomial)malloc(sizeof(struct PolyNode));
    front = rear; // 由 front 记录结果多项式链表头节点
    while (P1 && P2)
    { // 当两个多项式都有非零项待处理时
        switch (Compare(P1->expon, P2->expon))
        {
            case 1:
                Attach(P1->coef, P1->expon, &rear);
                P1 = P1->link;
                break;
            case -1:
                Attach(P2->coef, P2->expon, &rear);
                P2 = P2->link;
                break;
            case 0:
                sum = P1->coef + P2->coef;
                if (sum) Attach(sum, P1->expon, &rear);
                P1 = P1->link;
                P2 = P2->link;
                break;
        }
    }
    // 将未处理完的另一个多项式的所有节点依次复制到结果多项式中去
    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;
    temp = front;
    front = front->link; // 令 front 指向结果多项式的第一个非零项
    free(temp); // 释放临时空表头节点
    return front;
}


// 多项式的乘法
Polynomial PolyMult(Polynomial P1, Polynomial P2)
{
    Polynomial P, Rear, t1, t2, t;
    int c, e;

    if (!P1 || !P2) return NULL;

    t1 = P1;
    P = (Polynomial)malloc(sizeof(struct PolyNode));
    P->link = NULL;
    while (t1)
    {
        t2 = P2; // 每次循环之后要把 t2 归位到链表的开头
        Rear = P; // 每一次循环都要重新初始化 Rear,使 Rear 的初始值指向链表头
        while (t2)
        {
            c = t1->coef + t2->coef;
            e = t1->expon + t2->expon;
            while (Rear->link && Rear->link->expon > e) // 注意,这里和 e 作比较的是 Rear 的下一个节点中的值,这样下面的插入操作才解释得通
                Rear = Rear->link;
            if (Rear->link && Rear->link->expon == e) {
                if (Rear->link->coef + c)
                    Rear->link->coef += c;
                else { // 系数相加等于 0 的情况,要把该节点删掉
                    t = Rear->link;
                    Rear->link = t->link;
                    free(t);
                }
            } else { // 指数相加啊小于尾节点指数的情况,直接附加到结尾就成
                t = (Polynomial)malloc(sizeof(struct PolyNode));
                t->coef = c;
                t->expon = e;
                t->link = Rear->link;
                Rear->link = t; // 直接将 t2 的值附加到
                Rear = Rear->link;
            }
            t2 = t2->link; // 指针往后移动
        }
        t1 = t1->link;
    }
    t2 = P;
    P = P->link;
    free(t2); // 释放第一个没有存储数据得节点

    return P;
}

// 输出多项式
void PrintPoly(Polynomial P)
{
    int flag = 0; // 辅助调整输出格式用

    if (!P) {
        printf("0 0\n");
        return;
    }

    while (P) {
        if (!flag)
            flag = 1;
        else
            printf(" 🔺 ");
        printf("%d %d", P->coef, P->expon);
        P = P->link;
    }
    printf("\n");
}

// 读入多项式
Polynomial ReadPoly()
{
    Polynomial P, Rear, t;
    int c, e, N;

    scanf("%d", &N);
    P = (Polynomial)malloc(sizeof(struct PolyNode)); // 链表头空姐点
    P->link = NULL;
    Rear = P; // 复制 P 到 Rear,这样就可以不修改 P
    while (N--) {
        scanf("%d %d", &c, &e);
        Attach(c, e, &Rear); // 将当前项插入多项式尾部
    }
    t = P;
    P = P->link;
    free(t); // 删除临时生成头节点(因为里面也没存储数据)
    return P;
}

main.c(测试函数)

#include "poly.h"

// 测试函数
int main()
{
    Polynomial P1, P2, PP, PS; // PP 表示多项式乘积 Product,PS表示多项式和 Summary

    P1 = ReadPoly();
    P2 = ReadPoly();
    PP = PolyMult(P1, P2);
    PrintPoly(PP);

    PS = PolyAdd(P1, P2);
    PrintPoly(PS);

    return 0;
}

测试样例输出:

20201019130000

posted @ 2020-10-19 13:01  模糊计算士  阅读(264)  评论(0)    收藏  举报