【实验目的】
1、掌握线性表的定义及其基本操作,如建立、查找、插入和删除等;
2、掌握线性表的两类不同的存储结构的描述方法,掌握单链表的建立、查找、插入和删除等算法。
【实验内容】
设计一个一元多项式简单计算器。
【实验要求】
以带表头结点的单链表形式存储多项式,多项式的项数存放在头结点中。
1、输入并建立多项式f和g;
2、建立多项式h=f+g;
3、输出多项式h,输出形式为整型序列,其中n为多项式的项数,ci和ei分别是第i项的系数和指数,序列按指数降序排列;
4、系统完成后,提交实验报告。
【实验步骤】
1、单链表的类型定义
2、各模块的功能
(1)多项式的创建
【算法步骤】
1)创建一个只有头结点的空链表;
2)根据多项式的项的个数n,循环n次执行以下操作:
生成一个新节点*s;
输入多项式当前项的系数和指数赋给新节点*s的数据域;
设置一个前驱节点pre,用于指向待找到的一个大于输入项的指数的节点的前驱,pre初始时指向头节点;
指针q初始化,指向首元结点;
循环向下逐个比较链表中当前节点中的值与输入项指数,找到第一个直达与输入项指数的节点*q;
将输入项节点*s插入*q和其前驱节点pre之间。
【算法描述】
/* 多项式的创建*/
void CreatePolyn(Polynomial& p, int n) //输入n项的系数和指数,建立表示多项式的有序列表P
{
p = new PNode;
Polynomial s , pre , q;
p->next = NULL; //先建立一个带头节点的单链表
int i;
for (i = 1; i <= n; ++i) //依次输入n个非零项
{
printf("请输入第%d系数和指数:\n", i);
s = new PNode; //生成新节点
scanf_s("%f,%d",&s->coef,&s->expn); //输入系数和指数
pre = p; //pre用于保存q的前驱,初值为头节点
q = p->next; //q初始化,指向首元结点
while (q && q->expn < s->expn) //通过比较指数找到第一个大于输入项指数的项*q
{
pre = q;
q = q->next;
}
s->next = q; //将输入项s插入*q和其前驱节点pre之间
pre->next = s;
}
(2)打印多项式
【算法步骤】
用while判断系数是否大于零、小于零、等于零。
【算法描述】
/*打印多项式.*/
void PrintPolyn(Polynomial &pre)
{
int w = 1;
Polynomial p= pre->next;
if (!p) {
putchar('0');
printf("\n");
return;
}
while (p)
{
if (p->coef > 0 && w != 1) /*多项式中某一项系数大于0,输出+号*/
{
putchar('+');
}
if (p->coef != 1 && p->coef != -1)/*多项式系数不是正负1*/
{
printf("%f", p->coef); /*%g表示以%f%e中较短的输出宽度输出单双精度实数*/
if (p->expn == 1) putchar('X'); /*若指数为1,输出X*/
else if (p->expn) printf("X^%d", p->expn); /*指数不为1,输出x^%d格式*/
}
else
{
if (p->coef == 1) /*系数为1*/
{
if (!p->expn) putchar('1');
else if (p->expn == 1) putchar('X');
else printf("X^%d", p->expn);
}
if (p->coef == -1)/*系数为-1*/
{
if (!p->expn) printf("-1");
else if (p->expn == 1) printf("-X");
else printf("-X^%d", p->expn);
}
}
p = p->next;
w++;
}
printf("\n");
}
(3)多项式的相加
【算法步骤】
【算法描述】
/*多项式的相加*/
void AddPolyn(Polynomial& Pa, Polynomial& Pb)
{ /*多项式加法:Pa=Pa+Pb,利用两个多项式的节点构成“和多项式”*/
PNode* f, * g, * h, * r;
f = Pa->next;
g = Pb->next;/*f和g初始时分别指向Pa和Pb的首元节点*/
h = Pa;/*h指向多项式的当前节点,初值为Pa*/
int sum = 0;
while (f && g) /*f和g均非空*/
{
if (f->expn == g->expn) /*指数相等*/
{
sum = f->coef + g->coef;/*sum保存两项的系数和*/
if (sum != 0) /*系数和不为0*/
{
f->coef = sum; /*修改Pa当前指向节点的系数值为两项系数的和*/
h->next = f;
h = f;/*将修改后的Pa当前指向节点连接在h之后,h指向f*/
f = f->next;/*f指向后一项*/
r = g;
g = g->next;
delete r;/*删除Pb当前指向节点,g指向后一项*/
}
else/*系数和为零*/
{
r = f;
f = f->next;
delete r;/*删除Pa当前指向节点,f指向后一项*/
r = g;
g = g->next;
delete r;/*删除Pb当前指向节点,g指向后一项*/
}
}
else if (f->expn < g->expn)/*Pa当前指向节点的指数值小*/
{
h->next = f;/*将f链接在h之后*/
h = f; /*h指向f*/
f = f->next;/*f指向后一项*/
}
else /*Pb当前指向当前的指数值小*/
{
h->next = g;/*将g链接在h之后*/
h = g;/*h指向g*/
g = g->next;/*g指向后一项*/
}
}
h->next = f ? f : g;/*插入空多项式的剩余段*/
delete Pb;/*释放Pb的头结点*/
PrintPolyn(Pa);
}
(4)主函数
【算法描述】
int main() {
PNode* f, * g;
int n1, n2;
printf("请输入f的项数\n");
scanf_s("%d", &n1);
CreatePolyn(f, n1);
printf("多项式f=");
PrintPolyn(f);
printf("请输入g的项数\n");
scanf_s("%d", &n2);
CreatePolyn(g, n2);
printf("多项式g=");
PrintPolyn(g);
printf("多项式f和g的和为:h=");
AddPolyn(f, g);
return 0;
}
3、各模块之间的调用关系
4、主要算法的流程图
四、实验总代码及运行结果
【源程序代码】
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
/*单链表类型定义*/
typedef struct PNode {
float coef; //系数
int expn; //指数
struct PNode* next; //指针域
}PNode, * Polynomial; //Polynomial为指向结构体PNode的指针类型
/* 多项式的创建*/
void CreatePolyn(Polynomial& p, int n) //输入n项的系数和指数,建立表示多项式的有序列表P
{
p = new PNode;
Polynomial s , pre , q;
p->next = NULL; //先建立一个带头节点的单链表
int i;
for (i = 1; i <= n; ++i) //依次输入n个非零项
{
printf("请输入第%d系数和指数:\n", i);
s = new PNode; //生成新节点
scanf_s("%f,%d",&s->coef,&s->expn); //输入系数和指数
pre = p; //pre用于保存q的前驱,初值为头节点
q = p->next; //q初始化,指向首元结点
while (q && q->expn < s->expn) //通过比较指数找到第一个大于输入项指数的项*q
{
pre = q;
q = q->next;
}
s->next = q; //将输入项s插入*q和其前驱节点pre之间
pre->next = s;
}
}
/*打印多项式.*/
void PrintPolyn(Polynomial &pre)
{
int w = 1;
Polynomial p= pre->next;
if (!p) {
putchar('0');
printf("\n");
return;
}
while (p)
{
if (p->coef > 0 && w != 1) /*多项式中某一项系数大于0,输出+号*/
{
putchar('+');
}
if (p->coef != 1 && p->coef != -1)/*多项式系数不是正负1*/
{
printf("%f", p->coef); /*%g表示以%f%e中较短的输出宽度输出单双精度实数*/
if (p->expn == 1) putchar('X'); /*若指数为1,输出X*/
else if (p->expn) printf("X^%d", p->expn); /*指数不为1,输出x^%d格式*/
}
else
{
if (p->coef == 1) /*系数为1*/
{
if (!p->expn) putchar('1');
else if (p->expn == 1) putchar('X');
else printf("X^%d", p->expn);
}
if (p->coef == -1)/*系数为-1*/
{
if (!p->expn) printf("-1");
else if (p->expn == 1) printf("-X");
else printf("-X^%d", p->expn);
}
}
p = p->next;
w++;
}
printf("\n");
}
/*多项式的相加*/
void AddPolyn(Polynomial& Pa, Polynomial& Pb)
{ /*多项式加法:Pa=Pa+Pb,利用两个多项式的节点构成“和多项式”*/
PNode* f, * g, * h, * r;
f = Pa->next;
g = Pb->next;/*f和g初始时分别指向Pa和Pb的首元节点*/
h = Pa;/*h指向多项式的当前节点,初值为Pa*/
int sum = 0;
while (f && g) /*f和g均非空*/
{
if (f->expn == g->expn) /*指数相等*/
{
sum = f->coef + g->coef;/*sum保存两项的系数和*/
if (sum != 0) /*系数和不为0*/
{
f->coef = sum; /*修改Pa当前指向节点的系数值为两项系数的和*/
h->next = f;
h = f;/*将修改后的Pa当前指向节点连接在h之后,h指向f*/
f = f->next;/*f指向后一项*/
r = g;
g = g->next;
delete r;/*删除Pb当前指向节点,g指向后一项*/
}
else/*系数和为零*/
{
r = f;
f = f->next;
delete r;/*删除Pa当前指向节点,f指向后一项*/
r = g;
g = g->next;
delete r;/*删除Pb当前指向节点,g指向后一项*/
}
}
else if (f->expn < g->expn)/*Pa当前指向节点的指数值小*/
{
h->next = f;/*将f链接在h之后*/
h = f; /*h指向f*/
f = f->next;/*f指向后一项*/
}
else /*Pb当前指向当前的指数值小*/
{
h->next = g;/*将g链接在h之后*/
h = g;/*h指向g*/
g = g->next;/*g指向后一项*/
}
}
h->next = f ? f : g;/*插入空多项式的剩余段*/
delete Pb;/*释放Pb的头结点*/
PrintPolyn(Pa);
}
int main() {
PNode* f, * g;
int n1, n2;
printf("请输入f的项数\n");
scanf_s("%d", &n1);
CreatePolyn(f, n1);
printf("多项式f=");
PrintPolyn(f);
printf("请输入g的项数\n");
scanf_s("%d", &n2);
CreatePolyn(g, n2);
printf("多项式g=");
PrintPolyn(g);
printf("多项式f和g的和为:h=");
AddPolyn(f, g);
return 0;
}
【程序运行结果分析】