一元多项式的表示、相加与相乘.
本博客用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
#include //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.expndata,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