一元多项式的表示、相加与相乘 -数据结构课程设计

一元多项式的表示、相加与相乘.
本博客用C/C++实现。
参考数据结构课本。

先看效果图 最终的效果!!!

当然输出板的颜色做了些许调整,调回黑白很简单!!!

首页

在这里插入图片描述

加法操作

在这里插入图片描述

在这里插入图片描述

乘法操作

在这里插入图片描述
在这里插入图片描述

结束界面

在这里插入图片描述
Thanks 打的有点简略,但还是可以看出来的 hhhhh !!

先几点声明 (代码在最后)

·代码大体框架和函数名参考的是《数据结构》(C语言版)–严蔚敏 吴伟昌
1.LinkList P37
2.Polynomial P40

·程序用的C语言实现的,但因为书中给出的函数头有用到&进行传址操作,所以创建的是CPP文件(因为C文件不支持&)也就是说程序是在CPP文件里用的C语言实现。
所以可以将&传参的地方改为*传参,就是正宗的C语言;而将printf等改为cout,也可变为正统C++;但不建议修改,因为牵一发动全身,程序的逻辑很强,结构也不简单。

·本程序是用用项目实现的,不是单纯的.cpp/.c文件;没建立过项目的读者可以参考:https://blog.csdn.net/weixin_43731369/article/details/88828064

程序中用到system函数实现了清屏 暂停等功能;包括输出面板的前景色和后景色也是用system改的;具体实现参考:https://blog.csdn.net/weixin_43731369/article/details/88828520

Base.h
对需要的常量和数据类型进行定义,具体见代码注释。

#include<stdio.h>
#include <stdlib.h>  //malloc system
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
//Status是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef struct term //项的表示,多项式的项作为LinkList的数据元素
{
    float coef;//系数
    int expn;//指数
    bool operator==(const term t)const
    {
        return(this->coef == t.coef&&this->expn == t.expn);
    }
    bool operator!=(const term t)const
    {
        return(this->coef != t.coef || this->expn != t.expn);  //运算符重载
    }
} term,ElemType; //两个类型:term用于本ADT,ElemType为LinkList的数据对象名;
/*------线性表的定义---------*/
typedef struct LNode //节点类型
{
    ElemType  data;//这里表示了每一项,其指数和系数
    struct LNode *next;
}*Link,*Position;
typedef struct //链表类型
{
    Link head, tail;//分别指向线性链表中的头结点和最后一个结点
    int len;//指示线性链表中数据元素的个数
} LinkList; //每一项组成一个列表
typedef LinkList polynomial;

LinkList.h
线性表及其基本操作

//----------链表函数的具体实现代码-----------
Status MakeNode(Link &p, ElemType e)
{
    // 分配由p指向的值为e的结点,并返回OK;若分配失败。则返回ERROR
    p = (Link)malloc(sizeof(LNode));
    if (!p)
        return ERROR;
    p->data = e;
    return OK;
}//MakeNode
void FreeNode(Link &p)
{
    // 释放p所指结点
    free(p);
}//FreeNode
Status InitList(LinkList &L)
{
    // 构造一个空的线性链表
    Link p;
    p = (Link)malloc(sizeof(LNode)); // 生成头结点
    if (p)
    {
        p->next = NULL;
        L.head = L.tail = p;
        L.len = 0;
        return OK;
    }
    else
        return ERROR;//内存分配不够
}//InitList
Status DelFirst( Link h, Link &q)
{
    // h指向L的一个结点,把h当做头结点,删除链表中的第一个结点并以q返回。
    // 若链表为空(h指向尾结点),q=NULL,返回FALSE
    if(h->next==NULL) return ERROR;
    q = h->next;
    h->next = q->next;
    q->next = NULL;
    return OK;
}//DelFirst
Status ClearList(LinkList &L)
{
//将线性表L制空,并释放原链表的结点空间
    Link q;
    while(DelFirst( L.head, q))
    {
        free(q);
    }
    L.len=0;
    L.tail=L.head;
    return OK;
}
Status DestroyList(LinkList &L)
{
//销毁线性表L,L不负存在
    ClearList(L);
    free(L.head);
    return OK;
}
Status InsFirst(Link h, Link s)
{
// h指向L的一个结点,把h当做头结点,将s所指结点插入在第一个结点之前
    s->next = h->next;
    h->next = s;
    return OK;
}//InsFirst
Status Append(LinkList &L, Link s)
{
    // 将指针s(s->data为第一个数据元素)所指(彼此以指针相链,以NULL结尾)的
    //  一串结点链接在线性链表L的最后一个结点之后,并改变链表L的尾指针指向新
    //  的尾结点
    int i = 1;
    L.tail->next = s;
    while (s->next)
    {
        s = s->next;
        i++;
    }
    L.tail = s;
    L.len += i;
    return OK;
}//Append
Position GetHead(LinkList L)
{
    // 返回线性链表L中头结点的位置
    return L.head;
}//GetHead
Status SetCurElem(Link &p, ElemType e)
{
    // 已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值
    p->data = e;
    return OK;
}//SetCurElem
Position PriorPos(LinkList L,Link p)
{
    // 已知p指向线性链表L中的一个结点,返回p所指结点的直接前驱的位置
    //  若无前驱,则返回NULL
    Link q = L.head;
    if(q->next->data == p->data) return NULL;
    do
    {
        q=q->next;
    }
    while(q->next->data != p->data);
    return q;
}//PriorPos
Status ListEmpty(LinkList L)
{
    // 若线性链表L为空表,则返回TRUE,否则返回FALSE
    if (L.len)
        return FALSE;
    else
        return TRUE;
}//ListEmpty
Status LocateElemP(LinkList L, ElemType e,Position &q, int(*compare)(ElemType, ElemType))
{
    // 若升序链表L中存在与e满足判定函数cprintf(("**"));ompare()取值为0的元素,则q指示L中
    // 第一个值为e的结点的位置,并返回TRUE;否则q指示第一个与e满足判定函数
    // compare()取值>0的元素的前驱的位置。并返回FALSE。(用于一元多项式)
    Link p = L.head;
    if( ListEmpty(L) || compare(p->next->data, e)>0 )
    {
        q=p;
        return FALSE;
    }
    do
    {
        p = p->next;
    }
    while (p && (compare(p->data, e)<0));   // 没到表尾且p->data.expn<e.expn
    if (!p) // 到表尾或compare(p->data,e)>0
    {
        q = L.tail;
        return FALSE;
    }
    else if(compare(p->data, e)>0) // 找到
    {
        q = PriorPos(L,p);
        return FALSE;
    }
    else
    {
        q=p;
        return TRUE;
    }
}//LocateElemP
Position NextPos(Link p)
{
    // 已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的位置
    //  若无后继,则返回NULL
    return p->next;
}//NextPos
ElemType GetCurElem(Link p)
{
    // 已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值
    return p->data;
}//GetCurElem

Polynomial.h
多项式的基本操作

int cmp(term a, term b) // CreatPolyn()的实参
{
// 依a的指数值<、=或>b的指数值,分别返回-1、0或+1
    if (a.expn == b.expn)
        return 0;
    else if(a.expn > b.expn)
        return 1;
    else
        return -1;
}//cmp
void CreatPolyn(polynomial &P,int m)
{
    //输入m项的系数和指数,建立表示一元多项式的有序链表P
    InitList(P);//初始化-多项式链表
    Link h = GetHead(P);//设置头结点的数据元素
    term e = {0.0,-1}; //头结点设置
    Position q,s;
    SetCurElem(h, e);//设置头结点的元素
    for (int i = 1; i <= m; ++i)//依次输入m个非零项
    {
        printf("第%d项的系数:",i);
        scanf("%f",&e.coef);
        printf("第%d项的指数:",i);
        scanf("%d",&e.expn);
        if (!LocateElemP(P,e,q,(*cmp)))//当前链表中不存在该指数项
        {
                if (MakeNode(s, e))
                {
                    if(q->next==NULL) P.tail=s;
                    InsFirst(q,s);//生成结点并插入链表
                    P.len++;//课本上没有,感觉这个很有必要;
                }
        }
    }
}//CreatPolyn
int PolynLength(polynomial p)
{
    //返回一元多项式的长度
    return p.len;
}//PolynLength
void AddPolyn(polynomial &Pa, polynomial &Pb)
{
    //多项式加法:Pa = Pa+Pb,利用两个多项式的结点构成“和多项式”
    Position ha, hb, qa, qb;
    term a, b;
    float sum=0;
    ha = GetHead(Pa);
    hb = GetHead(Pb);//ha和hb分别指向Pa和Pb的头结点
    qa = NextPos(ha);
    qb = NextPos(hb);//qa和qb分别指向Pa和Pb中的当前结点
    //此时qa和qb都是指向多项式第一项
    while (qa && qb)//qa和qb非空
    {
        a = GetCurElem(qa);
        b = GetCurElem(qb); // a和b为两表中当前比较元素
        sum = 0;
        switch (cmp(a, b))//比较两者的指数值
        {
        case -1://多项式中PA中的结点的指数小
            ha = qa;
            qa = NextPos(ha);
            break;
        case 0://两者指数值相等
            sum = a.coef + b.coef;
            if (sum != 0)
            {
                //修改pa指向的该结点的系数值
                qa->data.coef = sum;
                //下一个
                ha = qa;
            }
            else
            {
                //删除结点
                Pa.len-=DelFirst( ha, qa);
                FreeNode(qa);
            }
            Pb.len-=DelFirst( hb, qb);//也删除掉qb的结点
            FreeNode(qb);//释放qb的空间
            //都往后移动一位
            qb = NextPos(hb);
            qa = NextPos(ha);
            break;
        case 1://多项式PB中的当前结点指数值小
            Pb.len-=DelFirst(hb, qb);//把当前结点从PB中删除,并用qb指向当前结点用以插入
            Pa.len+=InsFirst(ha, qb);//插入在ha前
            qb = NextPos(hb);
            qa = NextPos(ha);
            break;
        }//switch
    }//while
    if (!ListEmpty(Pb))
        Append(Pa, qb);//连接Pb中剩余结点
    FreeNode(hb);//释放Pb的头结点
}//AddPolyn
void MultiplyPolyn( polynomial &Pa, polynomial &Pb)
{
    //完成多项式乘法运算,即:PAxPb,并销毁一元多项式Pb
    Position ha, hb, qa, qb,s;
    polynomial Pc,Pd;
    InitList(Pd);
    term e;
    hb = GetHead(Pb);//ha和hb分别指向Pa和Pb的头结点
    qb = NextPos(hb);//qa和qb分别指向Pa和Pb中的当前结点
    while(qb)
    {
        ha = GetHead(Pa);
        qa = NextPos(ha);
        while(qa)
        {
            InitList(Pc);
            e.coef=qa->data.coef*qb->data.coef;
            e.expn=qa->data.expn+qb->data.expn;
            MakeNode(s,e);
            InsFirst(Pc.tail,s);
            Pc.tail=s;
            Pc.len++;
            ha=qa;
            qa=NextPos(ha);
        }
        AddPolyn(Pd,Pc);
        hb=qb;
        qb=NextPos(hb);
        FreeNode(hb);
    }
    DestroyList(Pb);
    Pa.head=Pd.head;
    Pa.tail=Pd.tail;
    Pa.len=Pd.len;
    FreeNode(Pd.head);
}
Status ListTraverse(LinkList L, void(*visit)(ElemType)){
    // 依次对L的每个数据元素调用函数visit()。一旦visit()失败,则操作失败
    Link p = L.head->next;
    int j;
    for (j = 1; j <= L.len; j++)
    {
        visit(p->data);
        p = p->next;
    }
    printf("\b "); //退格,每次输出多项式后删掉的最后输出的"+"
    if (L.len == 0)
        printf("0");
    return OK;
}//ListTraverse
void visit(ElemType e){
    if (e.coef > 0 && e.coef != 1 && e.expn != 0)
    {
        if(e.expn == 1)
            printf("%gx+", e.coef);
        else if  (e.expn > 0)
            printf("%gx^%d+", e.coef,e.expn);
    }
    else if (e.coef < 0 && e.expn != 0)
    {
        if(e.expn == 1)
            printf("(%g)x+", e.coef);
        else if (e.expn > 0)
            printf("(%g)x^%d+", e.coef,e.expn);
    }
    else if (e.coef == 1 && e.expn != 0)
    {
        if(e.expn == 1)
            printf("x+" );
        else if (e.expn > 0)
            printf("x^%d+",e.expn);
    }
    else if (e.expn == 0 && e.coef != 0)
        printf("%g+",e.coef);
    else;
}//visit
void PrintPolyn(polynomial P)
{
    //打印出一元多项式
    ListTraverse(P, visit);
    printf("\n");
}

Print.h
各种输出 菜单 和结束提示

void start_print()
{
    printf("***********************************************************************************************************************\n");
    printf("                  数据结构实验一                         \n");
    printf("          一元多项式的表示、相加和乘法                   \n");
    printf("                 中国海洋大学                            \n");
    printf("***********************************************************************************************************************\n");
}
void Creathelp_print(int & m)
{
    printf("**请输入多项式的项数**\n");
    scanf("%d",&m);
    printf("**请输入多项式的系数和指数**\n");
}
void menu1_print()
{
    printf("***********************************************************************************************************************\n");
    printf("        请选择  1.建立多项式(重新输入) A   2.建立多项式(重新输入) B   3.对多项式进行操作    0.退出                \n");
    printf("***********************************************************************************************************************\n");
}
void menu2_print()
{
    printf("***********************************************************************************************************************\n");
    printf("        请选择  1.打印 A+B   2.打印 AXB    3.对多项式进行操作    0.退出                \n");
    printf("***********************************************************************************************************************\n");
}
void output_tip_print(char a)
{
    printf("多项式%c: ",a);
}
void over_print()
{
    system("CLS");
    printf("      *******  *               *           \n");
    printf("         *     *               *           \n");
    printf("         *     ***  ***   ***  * *   **    \n");
    printf("         *     * *  * *   * *  **    *     \n");
    printf("         *     * *  ****  * *  * *  **     \n");
}

main.cpp
.cpp 不是.c 一定注意!!!!!!!!!!!!!!
主函数逻辑控制

#include"Base.h"
#include"LinkList.h"
#include"Polynomial.h"
#include"Print.h"
int main()
{
    system("color F4");
    start_print();
    system("pause");
    system("CLS");
    polynomial A,B;
    int a,m;// a进行输入控制
    do
    {
        system("CLS");
        do
        {
            menu1_print();
            scanf("%d",&a);
            if(a==1)
            {
                Creathelp_print(m);
                CreatPolyn(A,m);
            }
            else if(a==2)
            {
                Creathelp_print(m);
                CreatPolyn(B,m);
            }
            else if(a==0)
            {
                over_print();
                return 0;
            }
        }
        while(a!=3);
        do
        {
            menu2_print();
            scanf("%d",&a);
            if(a==1)
            {
                output_tip_print('A');
                PrintPolyn(A);
                output_tip_print('B');
                PrintPolyn(B);
                AddPolyn(A, B);
                printf("A+B: ");
                PrintPolyn(A);
                system("pause");
                break;
            }
            else if(a==2)
            {
                output_tip_print('A');
                PrintPolyn(A);
                output_tip_print('B');
                PrintPolyn(B);
                MultiplyPolyn(A,B);
                printf("AXB: ");
                PrintPolyn(A);
                system("pause");
                break;
            }
            else if(a==0)
            {
                over_print();
                return 0;
            }
        }
        while(a!=3);
    }
    while(1);
}

有任何不解,请看代码之前的解释说明,及给出的相关连接;或者直接评论!
码码不易,码字更不易,点个赞呗!
谢谢,转载请注明出处:https://blog.csdn.net/weixin_43731369/article/details/88824961

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值