两个一元多项式加减乘运算的链表实现

        本节讨论如何用带头结点的线性链表的基本操作来实现一元多项式的加减乘运算。

       由于笔者使用的是严蔚敏的《数据结构》,故本解决方案主要来自教材37页和42页的整合。而代码的风格仿照B站的数据结构老师王卓。

        程序分为一个主文件main.cpp和头文件operator.h。具体如下:

mian.cpp

#include <iostream>
#include "operator.h"

using namespace std;

int main(){
    LinkList Pa,Pb;
    int choice = 1;
    while(1){
        display();
        cout<<"请输入操作:";
        cin>>choice;
        switch(choice){
            case 1:
                input(Pa,Pb);
                AddList(Pa,Pb);
                cout<<"以上两个式子相加的多项式为:";
                PrintList(Pa);
                break;
            case 2:
                input(Pa,Pb);
                SubtractList(Pa,Pb);
                cout<<"以上两个式子相减的多项式为:";
                PrintList(Pa);
                break;
            case 3:
                input(Pa,Pb);
                MultiplyList(Pa,Pb);
                cout<<"以上两个式子相乘的多项式为:";
                PrintList(Pa);
                break;
            case 0:
                return 0;
            }//switch
    }//while
}//main

operator.h

#include <iostream>

using namespace std;

//预定义类型和变量
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0

//Status是函数的类型,其值是函数结果状态代码
typedef int Status;

//一个带头结点的链表
typedef struct{ //数据类型
    float coef; //系数
    int expn;   //指数
}ElemType,term;

typedef struct LNode{   //结点类型
    ElemType data;
    struct LNode *next;
}LNode, *LinkList;

Status MakeNode(LinkList &p,ElemType e){
    //分配由p指向的值为e的结点,并返回OK;若分配失败,则返回ERROR
    p = new LNode;
    if(!p) 
        return ERROR;
    p->data = e;
    p->next = NULL;
    return OK;
}//MakeNode

Status FreeNode(LinkList &p){
    //释放p所值的结点
    delete p;
    p = NULL;
    return OK;
}//FreeNode

Status DeleteNode(LinkList &pa,LinkList &pb){
    //删除pa后面的结点pb
    pa->next = pb->next;
    return OK;
}//DeleteNode

LinkList PriorNode(LinkList L,LinkList p){
    //搜索链表L中结点p的前一个结点
    LinkList q;
    q = L->next;
    if(q == p){
        return NULL;
    }//if
    else{
        while(q->next != p){
            q = q->next;
        }
        return q;
    }//else
}//PriorNode

Status InitList(LinkList &L){
    //构造一个空的线性链表
    L = new LNode;
    L->next = NULL;
    return OK;
}//InitList

Status CreateList(LinkList &L){
    //创建新的链表
    InitList(L);
    cout<<"请分别输入链表的系数和指数,当指数为-1时停止输入:"<<endl;
    LNode *s,*r;
    r = L;
    ElemType e;
    cin>>e.coef>>e.expn;
    while(e.expn != -1){
        s = new LNode;
        s->data = e;
        r->next = s;
        r = s;
        cin>>e.coef>>e.expn;
    }
    r->next = NULL;
    return OK;
}//CreateList

Status DestroyList(LinkList &L){
    //销毁线性链表L,L不再存在
    LNode *p;
    while(L){
        p = L;
        L = L->next;
        delete p;
    }   
    return OK;
}//DestroyList

Status ClearList(LinkList &L){
    //将线性链表L重置为空表,并释放原链表的结点空间
    LNode *p,*s;
    p = L->next;
    while(p){
        s = p->next;
        delete p;
        p = s;
    }
    L->next = NULL;
    return OK;
}//ClearList

void PrintList(LinkList L){
    LinkList p;
    p = L->next;
    while(p){
        cout<<p->data.coef<<"*x^"<<p->data.expn;
        p = p->next;
        if(p && p->data.coef>0) cout<<"+";
    }//while
    cout<<endl;
}//PrintList

int compare(term a,term b){
    //比较链表指数的大小,小于,等于,大于返回-1 0 1
    if(a.expn<b.expn) return -1;
    if(a.expn>b.expn) return 1;
    return 0;
}//compare

void OppositeList(LinkList &L){
    LinkList p;
    p = L->next;
    while(p){
        p->data.coef *= -1;
        p = p->next;
    }
}//OppositeList

Status LocateElemP(LinkList L,ElemType e,LinkList &q,int (*compare)(term,term)){
    //若有序链表L中存在与e满足有序判定函数compare()取值为0的元素,则q指示L中第一个值为e的结点位置,并返回TRUE
    //否则,q指示第一个与e满足有序判定函数compare()取值为1的元素的前驱,并返回FALSE
    LinkList prior,p;
    p = L;    //p指向当前结点
    do{
        prior = p;
        p = p->next;
    }while(p && (*compare)(p->data,e)<0);
    if(!p || compare(p->data,e)>0){
        q = prior;
        return FALSE;
    }//if
    else{
        q = p;
        return TRUE;
    }//else
}//LocateElemP

void OrderInsert(LinkList &L,ElemType e,int (*compare)(ElemType,ElemType)){
    //按有序判定函数compare()的约定,将值为e的结点插入到有序链表L的适当位置上
    LinkList p,q;
    if(LocateElemP(L,e,q,compare)){ //链表中存在该指数项
        q->data.coef += e.coef;
        if(!q->data.coef){          //系数为0
            p = PriorNode(L,q);
            if(!p) p = L;
            DeleteNode(p,q);
            FreeNode(q);
        }//if
    }//if
    else{   //链表中不存在该指数项
        MakeNode(p,e);  //创建结点 插入
        p->next = q->next;
        q->next = p;
    }//else
}//OrderInnsert

void AddList(LinkList &La,LinkList &Lb){
    //链表La = La+Lb
    LinkList ha,hb; //头结点
    LinkList pa,pb; //当前结点
    ha = La;  pa = ha->next;
    hb = Lb;  pb = hb->next;
    float sum;
    while(pa && pb){
        switch(compare(pa->data,pb->data)){
            case -1:    //链表La当前结点的指数小于链表Lb
                ha = pa;
                pa = pa->next;
                break;
            case 0:     //两个链表当前结点指数相等
                sum = pa->data.coef+pb->data.coef;
                if(sum != 0.0){  //相加不等于0
                    pa->data.coef = sum;
                    ha = pa;
                }
                else{    //相加等于0
                    DeleteNode(ha,pa);  //删除结点pa
                    FreeNode(pa);
                }
                //删除结点pb
                DeleteNode(hb,pb);
                FreeNode(pb);
                pb = hb->next;
                pa = ha->next;
                break;
            case 1:     //链表La当前结点的指数大于链表Lb
                DeleteNode(hb,pb);      //Lb
                pb->next = ha->next;    //La
                ha->next = pb;
                pb = hb->next;
                ha = ha->next;
                break;
        }//switch
    }//while
    if(pb) ha->next = pb;          //将Lb剩下的子链接到Lb
    FreeNode(hb);
}//AddList

void SubtractList(LinkList &La,LinkList &Lb){
    //La = La-Lb
    OppositeList(Lb);   //链表Lb变为相反数
    AddList(La,Lb);
}//SubtractList

void MultiplyList(LinkList &La,LinkList &Lb){
    //多项式相乘La = La*Lb
    LinkList Lc;    //临时多项式链表Lc
    InitList(Lc);   //初始化Lc
    LinkList pa,pb;
    term a,b,c;
    pa = La;
    if(La->next!=NULL && Lb->next!=NULL){
        pa = pa->next;
        while(pa){
            a = pa->data;
            pb = Lb->next;
            while(pb){
                b = pb->data;
                c.coef = a.coef*b.coef;
                c.expn = a.expn+b.expn;
                OrderInsert(Lc,c,compare);
                pb = pb->next;
            }//while
            pa = pa->next;
        }//while
        DestroyList(Lb);
        ClearList(La);
        La = Lc;
    }//if
    else{
        //do nothing链表为空
    }//else
}//MultiplyList

//显示界面
void display(){
    cout<<"---一元多项式四则运算---"<<endl;
	cout<<"---输入数字1选择相加----"<<endl;
	cout<<"---输入数字2选择相减----"<<endl;
	cout<<"---输入数字3选择相乘----"<<endl;
	cout<<"---输入数字0选择退出----"<<endl;
}//display

//输入界面
void input(LinkList &La,LinkList &Lb){
	cout<<"请输入第一个多项式:"<<endl;
	CreateList(La);
	PrintList(La);
	
	cout<<"请输入第二个多项式:"<<endl;
	CreateList(Lb);
	PrintList(Lb);
}//input

  • 9
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值