1. 实验目的
掌握线性表的链式存储结构设计与基本操作的实现。
2.实验内容与要求
(1)定义线性表的链式存储表示;
(2)基于所设计的存储结构实现线性表的基本操作;
(3)线性表的应用:设线性表L1和L2分别代表集合A和B,试设计算法求A和B的并集C,并用线性表L3代表集合C;
(4)设计一个一元多项式计算器,要求能够:
①输入并建立多项式;
②输出多项式;
③执行两个多项式相加;
3.算法思路
(1)求并集:
①定义链表表L1、L2、L3
②基于所设计的存储结构实现链表的基本操作:初始化、输入输出、查找元素
③定义并集的函数,首先将L1全部复制进L3,再用LocateElem函数判断L3中是否含有L2中的元素,有则跳过,没有就新建结点将元素用尾插法插入L3表中。
(2)多项式求和
①初始化多项式,输入多项式内容
②进行加法运算:
③重复执行②直到ha或hb为空
④若ha非空则将其所指剩余链表加入结果链表;若hb非空则将其所指剩余链表加入结果链表。
⚠️在进行第②步时仍然需要分为两步:
步骤 | 内容✍️ |
---|---|
1⃣️ | 令ha->pa中第一个结点,hb->pb中的第一个结点,hc->链表中的最后一个结点 |
2⃣️ | 比较ha和hb所指结点的指数:ha所指结点指数较小,将该结点插入结果链表,ha->下一结点,hc->新插入结点;hb所指结点指数较小,将该结点插入结果链表,hb->下一结点,hc->新插入结点;ha和hb所指结点指数相同,则将pb系数加到pa所指结点上:若两结点系数之和为0,两结点均销毁,ha、hb都指向下一结点;否则,ha所指结点插入结果链表,hb所指结点销毁,ha、hb均指向下一个结点。 |
4.上代码!
#include
using namespace std;
typedef struct LNode
{
int data;
struct LNode *next;
}LNode,*LinkList;
typedef struct Node
{
float coef; //系数
int expn; //指数
struct Node *next;
}Node,*polynomial;
void InitList(LinkList &L) //初始化链表
{
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL; //头结点
}
void Input(LinkList &L) //尾插法
{
LinkList end = L;
int n;
cout<<"请输入总数:"<<endl;
cin>>n;
cout<<"请输入数字:"<<endl;
for(int i = n; i > 0; i--)
{
LinkList node;
node = (LinkList)malloc(sizeof(LNode));
cin>>node->data;
end->next = node;
end = node;
end->next = NULL;
}
}
void Output(LinkList L)
{
LNode *p = L->next;
while(p)
{
cout<<p->data<<" ";
p = p->next;
}
cout<<endl;
}
int LocateElem(LinkList L,int e) //判断L3中是否有L2元素 ,有返回1,没有返回0
{
LinkList p = L->next;
while(p)
{
if(p->data == e)
return 1;
else
p = p->next;
}
return 0;
}
void Union(LinkList L1,LinkList L2,LinkList &L3) //求L1、L2并集
{
LinkList p,q,end_L3;
p = L1->next; //指向第一个结点
q = L2->next;
end_L3 = L3; //L3尾指针
while(p) //把L1的值全部赋给L3
{
LinkList node;
node = (LinkList)malloc(sizeof(LNode));
node->data = p->data;
end_L3->next = node;
end_L3 = node;
end_L3->next = NULL;
p = p->next;
}
while (q)
{
if(!LocateElem(L3, q->data)) //判断L3中是否有L2元素
{
//没有则插入
LinkList node;
node = (LinkList)malloc(sizeof(LNode));
node->data = q->data;
end_L3->next = node;
end_L3 = node;
end_L3->next = NULL;
q = q->next;
}
else
q = q->next;
}
}
//输入m项的系数和指数,建立表示一元多项式的带有头节点的有序链表P
//利用尾插法
void CreatePolyn(polynomial &P, int m)
{
P = (polynomial)malloc(sizeof(Node));
P->next = NULL;
polynomial end = P;
cout<<"请输入系数和指数(如5x^2输入(5 2)即可):"<<endl;
for(int i = 0; i < m; i++)
{
polynomial node =(polynomial)malloc(sizeof(Node));
cin>>node->coef>>node->expn;
end->next = node;
end = node;
end->next = NULL;
}
}
void AddPolyn(polynomial &pa,polynomial &pb) //多项式求和
{
polynomial ha = pa->next;
polynomial hb = pb->next;
polynomial hc = pa;
while(ha&&hb)
{
if(ha->expn < hb->expn) //ha的指数
{
hc->next = ha;
ha = ha->next;
hc = hc->next;
}
else if(ha->expn > hb->expn) //hb可插入
{
hc->next = hb;
hb = hb->next;
hc = hc->next;
}
else
{
ha->coef = ha->coef + hb->coef;
if(ha->coef) //和不为0
{
hc->next = ha;
ha = ha->next;
hc = hc->next;
hb = hb->next;
}
else
{
polynomial p = ha;
ha = ha->next;
free(p);
p = hb;
hb = hb->next;
free(p);
}
}
}
if(!ha)
hc->next = hb;
if(!hb)
hc->next = ha;
free(pb);
}
void Print(polynomial P)
{
polynomial p = P->next;
if(p == NULL) //多项式相加和为0时
{
cout<<0<<endl;
}
else
{
while (p->next)
{
if(p->expn == 0)
{
cout<<p->coef<<"+";
p = p->next;
}
else if(p->expn == 1)
{
cout<<p->coef<<"x"<<"+";
p = p->next;
}
else if(p->next->coef < 0)
{
cout<<p->coef<<"x^"<<p->expn;
p = p->next;
}
else if(p->coef < 0)
{
cout<<-(p->coef)<<"x^"<<p->expn<<"-";
p = p->next;
}
else
{
cout<<p->coef<<"x^"<<p->expn<<"+";
p = p->next;
}
}
cout<<p->coef<<"x^"<<p->expn<<endl;
}
}
int main()
{
cout<<"######链表求并集问题######"<<endl;
LinkList L1,L2,L3;
InitList(L1);
InitList(L2);
InitList(L3);
Input(L1);
Input(L2);
Union(L1,L2,L3);
cout<<"合并结果:"<<endl;
Output(L3);
cout<<endl;
cout<<"######一元多项式求和问题######"<<endl;
polynomial Pa,Pb;
int m1,m2;
cout<<"请分别输入多项式1和2的总项数:"<<endl;
cin>>m1>>m2;
CreatePolyn(Pa, m1);
CreatePolyn(Pb, m2);
cout<<"第一个一元多项式为:"<<endl;
Print(Pa);
cout<<"第二个一元多项式为:"<<endl;
Print(Pb);
cout<<"相加结果为:"<<endl;
AddPolyn(Pa, Pb);
Print(Pa);
}
5.运行结果
6.心得体会
第一次做题时忽略了并集有重复元素的情况,开始用了两种思路解决,第一个全部插入L3之后,遍历L3删除有重复元素的结点,但因为是无序排列,没有想出算法;第二种是通过查阅可以定义一维数组a,初始将其所有元素设为0,读到数x时,a[x]++,之后遍历时发现a[x]!=0说明是重复元素,需要删除。但这种方法占用存储空间太大,故舍去。最后使用了LocateElem函数,在插入前检查该L2元素是否已经存在在L3内。在做多项式时的输出需要考虑多种情况,指数和系数为1、0和负数时有着不同的输出方案。
帮助到你请点赞➕收藏➕关注哦~