一元多项式加法和减法(链表结构)

问题描述

问题如题目所示。

存储结构

  • 因为多项式的长度是不确定的,所以采用链表形式更加方便。
  • 多项式的每一项都包括一个系数和指数,所以需要自定义每一项的数据结构。
  • 由于在加法和减法操作中,有序的链表结构更加方便,所以可以创建有序链表。这里采用的方法是要求输入时就为指数递减输入(乱序输入,程序来排序的创建函数,后面会考虑补上)
//一元多项式项的表示
typedef struct{
    float c;    //系数
    int e;      //指数
}ElemType;

//链表结构
typedef struct SLNode
{
    ElemType val;
    struct SLNode *next;
}node, *LinkList;

基本操作

关于多项式的基本操作:

//建立有序链表
void CreatPoly(LinkList &P, int m);

//销毁一元多项式
void DestoryPoly(LinkList &P);

//打印输出一元多项式
void PrintPoly(LinkList P);

//返回一元多项式P中的项数
int PolyLength(LinkList P);

//多项式相加
void AddPoly(LinkList &Pa, LinkList &Pb, LinkList &Pc);

//多项式相减
void SubtractPoly(LinkList &Pa, LinkList &Pb, LinkList &Pc);

关于链表的基本操作:https://blog.csdn.net/qq_41856633/article/details/98873635
其中有一些改动,增加了一个函数:

//返回满足cmp的元素的索引
int getIndex(LinkList L, ElemType e, int (* compare)(ElemType, ElemType))
{
    LinkList p = L->next;
    int i = 1;
    while(p){
        if(compare(e, p->val) == 0) return i;
        i ++;
        p = p->next;
    }
    return i;
}

实现

  1. 初始化
//建立有序链表
void CreatPoly(LinkList &P, int m)
{
    Init_List(P);

    printf("请依次输入每一项的系数和指数,以空格区分。\n");
    for(int i = 0; i < m; i ++){
        ElemType data;
        scanf("%f %d", &data.c, &data.e);
        int index = getIndex(P, data, cmp);
        if(index <= PolyLength(P)){	//指数相同进行合并
            LinkList q = P;
            while(index -- ) q = q->next;
            q->val.c += data.c;
            continue;
        }
        bool flag = addElem(P, i + 1, data);
        if(!flag) return;
    }
}

在添加的时候,如果两次输入同一指数的项会进行合并。

  1. 打印多项式
//打印输出一元多项式
void PrintPoly(LinkList P)
{
    int length = PolyLength(P);
    for(int i = 0; i < length - 1; i++){
        ElemType data;
        getElem(P, i+1, data);
        printf("%.2fx^%d + ", data.c, data.e);
    }
    ElemType data;
    getElem(P, length, data);
    printf("%.2fx^%d\n", data.c, data.e);
}

这里,指数为0没有进行处理。(可以尝试在指数为0时只输出系数)

  1. 相加
//多项式相加
void AddPoly(LinkList &Pa, LinkList &Pb, LinkList &Pc)
{
    LinkList qa = Pa->next;
    LinkList qb = Pb->next;
    Init_List(Pc);
    LinkList qc = Pc;
    while(qa && qc){
        ElemType dataa = qa->val;
        ElemType datab = qb->val;

        if(dataa.e > datab.e){
            qc->next = qa;
            qa = qa->next;
        }else if(dataa.e < datab.e){
            qc->next = qb;
            qb = qb->next;
        }else{
            dataa.c += datab.c;
            if(dataa.c == 0){	//系数为0就直接删除结点
                LinkList s = qa;
                qa = qa->next;
                free(s);
                s = qb;
                qb = qb->next;
                free(s);
                continue;
            }
            qa->val.c = dataa.c;
            qc->next = qa;
            LinkList s = qb;
            qb = qb->next;
            qa = qa->next;
            free(s);
        }
        qc = qc->next;
    }
    if(qa){
      qc->next = qa;
    }
    if(qb){
        qc->next = qb;
    }
    free(Pa);
    free(Pb);
}

这里为了节约空间,只声明了一个新的Pc头结点,其他均用以有的结点进行连接。(运算完成后可以删除Pa和Pb的头结点).
介于减法就是Pb每一项乘以 -1 再和Pa相加,就不再写了。

小结

大致的基本操作就是这样(乘法相对比较繁琐,并且也是以加法为基础的,就没有写了。貌似没有看到乘法的考试要求,就不为难自己了…)
完整代码地址

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值