多项式相加和相乘
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef int ElemType;
typedef int Status;
const int maxn=3000;
const ll INF=1e18;
//---------------------------------------结构体定义区-----------------------------------
/* typedef struct item
{
int expn;//定义数据域的数据类型
}ElemType; */
typedef struct{
float coef;//系数
int expn;//指数
}term;
typedef struct Lnode//定义结点
{
term data;//数据域
struct Lnode *next;//指针域
}LNode,*LinkList;//将这个类型命名为LNode,并定义一个指向这个类型的指针
//----------------------------------------函数声明区------------------------------------
void CreateList_L(LinkList &L,int n);//头插法创建链表
void creatlist(LinkList &L,int n);//尾插法创建链表
void Creatpolyn(LinkList &L, int a);//创建多项式
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc);//链表的合并
void Orderinsertmerge(LinkList &L, term e);//按顺序插入项
void printpolyn(LinkList p);//打印多项式
void add(LinkList L1, LinkList L2, LinkList &L3);//多项式加法,结果以L3返回
void mult(LinkList L1,LinkList L2,LinkList &L4);//多项式乘法,结果以L4返回
void List(LinkList L); //打印链表
Status GetElem_L(LinkList L,int i,ElemType &e);//查找第i个元素并返回
Status ListInsert_L(LinkList&L,int i,ElemType e);//前插法:在带头结点的单链线性表L中第i个位置之前插入元素e
Status ListDelete_L(LinkList &L,int i,ElemType &e);//在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
//---------------------------------------函数定义区--------------------------------------
/*int ListInsert_L(LinkList &L,int i,ElemType e)
{ //在头结点的单链线性表L的第i个元素之前插入元素e
if(!LocatePos(L,i-1,h)) return 0;//i值不合法
if(!MakeNode(s,e)) return 0;//结点储存分配失败
InsFirst(h,s);//对于从第i哥结点开始的链表,第i-1个结点是它的头结点
return 0;
}*/
/*int MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc,int (*compare)(ElemType,ElemType))
{//La、Lb和Lc都是非递减序列
if(!InitList(Lc)) return 0;//储存空间分配失败
LinkList ha,hb;
ha=GetHead(La);hb=GetHead(Lb);//ha和hb分别指向La和Lb的头结点
pa=NextPos(La,ha),pb=NextPos(Lb,hb);//pa和pb分别指向La和Lb中当前结点
while(pa&pb)
{
a=GetCurElem(pa);b=GetCurElem(pb);//a、b为两表中当前比较元素
if((*compare)(a,b)<=0)
{
DelFirst(ha,q);Append(Lc,q);pa=NextPos(La,ha);
}else{
DelFirst(hb,q);Append(Lc,q);pb=NextPos(Lb,hb);
}
}
if(pa) Append(Lc,pa);//链接La中剩余结点
else Append(Lc,pb);//链接Lb中剩余结点
FreeNode(ha);FreeNode(hb);//释放两个头结点
return 1;
}*/
/*void CreatPolyn(polynomail &p,int m)
{ //输入m项的系数和指数,建立表示一元多项式的有序链表P
InitList(P);h=GetHead(P);
e.coef=0.0;e.expn=-1;SetCurElem(h,e);//设置头结点的数据元素
for(int i=1;i<=m;i++)//依次输入m个非零项
{
scanf(e.coef,e.expn);
if(!LocateElem(P,e,q,(*cmp)()))
{ //当前链表中不存在该指数项
if(MakeNode(s,e)) InsFirst(q,s);//生成结点并插入链表
}
}
}*/
/*void AddPolyn(polynomail &Pa,polynomail &Pb)
{//多项式加法;Pa=Pa+Pb,利用两个多项式的结点构成"和多项式"
ha=GetHead(Pa);hb=GetHead(Pb);//ha和hb分别指向Pa和Pb的头结点
qa=NextPos(Pa,ha);qb=NextPos(Pb,hb);//qa和qb分别指向Pa和Pb中当前结点
while(qa&&qb)
{
a=GetCurElem(qa);b=GetCurElem(qb);//a和b为当前比较的元素
switch (*cmp(a,b))
{
case -1://Pa指数小
ha=qa;qa=NextPos(Pa,qa);break;
case 0://二者的指数值相等
sum=a.coef+b.coef;
if(sum!=0.0)
{//修改多项式Pa中当前结点的系数值
SetCurElem(qa,sum);ha=qa;
}else{//删除多项式Pa中当前结点
DelFirst(ha,pa);FreeNode(qb);qb=NextPos(Pb,hb);
qa=NextPos(Pa,ha);break;
}
case 1://Pb指小
DelFirst(hb,qb);InsFirst(ha,qb);
qb=NextPos(Pb,hb);ha=NextPos(Pa,ha);break;
}
}
if(!ListEmpty(Pb)) Append(Pa,qb);//链接Pb中剩余结点
FreeNode(hb);//释放Pb的头结点
}*/
/* void CreateList_L(LinkList &L,int n)//头插法
{ //逆位序输入n个元素的值,建立带表头结点的单链线性表L
L=(LinkList)malloc(sizeof(Lnode));
LinkList p;
L->next=NULL;//先建立一个带头结点的单链表
for(int i=n;i>0;--i)
{
p=(LinkList)malloc(sizeof(Lnode));//生成新结点
scanf("%d",&p->data);//输入元素值
p->next=L->next;L->next=p;//插入到表头
}
} */
/* void creatlist(LinkList &L,int n)//尾插法
{ //尾插法创建链表
L=(LinkList)malloc(sizeof(Lnode));
LinkList p,r=NULL;//它们的类型都是指针
L->next=NULL;
for(int i=0;i<n;++i)
{
p=(LinkList)malloc(sizeof(Lnode));
//强制类型转换是指针,大小是结构体
scanf("%d",&p->data);
p->next=NULL;
if(L->next==NULL) L->next=p;
else r->next=p;//链接新创建的结点
r=p;//r的指向在不断改变
}
} */
/* Status GetElem_L(LinkList L,int i,ElemType &e)
{
//L是带头节点的单链表的头指针
//当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
LinkList p=L->next;int j=1;//初始化,p指向第一个结点,j为计数器
while(p&&j<i)
{ //顺指针向后查找,直到p指向第i个元素或p为空
p=p->next;++j;
}
if(!p||j>i)return 0;//遍历完发现第i个元素不存在
e=p->data;//取第i个元素
return 1;
} */
/* Status ListInsert_L(LinkList&L,int i,ElemType e)
{ //前插法:在带头结点的单链线性表L中第i个位置之前插入元素e
LinkList p=L;int j=0;//P为头结点,j为计数器
LinkList s;
while(p&&j<i-1)
{ //寻找第i-1个结点
p=p->next;++j;
}
if(!p||j>i-1) return 0;//i<1或者大于表长加1
s=(LinkList)malloc(sizeof(Lnode));//生成指向新结点的指针
s->data=e;s->next=p->next;//插入L中
p->next=s;
return 1;
} */
/* Status ListDelete_L(LinkList &L,int i,ElemType &e)
{ //在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
LinkList p=L;int j=0;
LinkList q; q=(LinkList)malloc(sizeof(Lnode));
while(p->next&&j<i-1)
{ //寻找第i个结点,并令p指向其前驱
p=p->next;++j;
}
if(!(p->next)||j>i-1) return 0;//删除位置不合理
q=p->next;p->next=q->next;//删除q结点,并释放
e=q->data;free(q);
return 1;
} */
/* void MergeList_Sq(SqList LA,SqList LB,SqList &LC){
pa = LA.elem;
pb = LB.elem; //指针pa和pb的初值分别指向两个表的第一个元素
LC.length = LA.length+LB.length; //新表长度为待合并两表的长度之和
LC.elem = new ElemType[LC.length]; //为合并后的新表分配一个数组空间
pc = LC.elem; //指针pc指向新表的第一个元素
pa_last = LA.elem+LA.length-1; //指针pa_last指向LA表的最后一个元素
pb_last = LB.elem+LB.length-1; //指针pb_last指向LB表的最后一个元素
while(pa <= pa_last && pb <= pb_last){ //两个表都非空
if(*pa <= *pb) *pc++ = *pa++; //依次“摘取”两表中值较小的结点
else *pc++ = *pb++;
}
//此时a,b 之中一定有一个表为空
while(pb <= pb_last) *pc++ = *pb++; //LB表已到达表尾
while(pa <= pa_last) *pc++ = *pa++; //LA表已到达表尾
} */
/* void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
//已知单链线性表La和Lb的元素按值非递减排列
//归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
LinkList pa,pb,pc;
pa=La->next; pb=Lb->next;
Lc=pc=La; //用La的头结点作为Lc的头结点
while(pa && pb){
if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next;}
else{pc->next=pb; pc=pb; pb=pb->next;}
}
pc->next=pa?pa:pb;//插入剩余段
//若pa不空,则pc->next = pa;,否则则为pc->next = pb;
free(Lb);//释放Lb的头结点
} */
/* void List(LinkList L)
{ //打印链表
LinkList p;
p=(LinkList)malloc(sizeof(Lnode));
//if(L->data) p=L;//没有头结点的链表
//else p=L->next;//有头结点的链表
p=L->next;
while(p)
{
printf("%d ",p->data);
p=p->next;
}
} */
void Creatpolyn(LinkList &L, int a)//创建多项式
{
L = (LinkList)malloc(sizeof(Lnode));
L->next = NULL;//建立头结点
term e;
for (int i = 1; i <= a; i++)
{
scanf("%f%d", &e.coef, &e.expn);
Orderinsertmerge(L, e);//将所读得的数据插入链表
}
}
void Orderinsertmerge(LinkList &L, term e)//按次数大小插入项(次数决定插入的位置)
{
LinkList p, q;//q为操作指针,p指针指向q的下一位以方便排序
p = L;//每次p都从头开始
LinkList o = (LinkList)malloc(sizeof(Lnode));//o为临时节点
while (p)//如果p=NULL,则跳出循环,在顺序表末尾添加结点
{
q = p;//通过循环移动指针q的位置
p = p->next;//将p指向NULL
if (e.coef == 0) return;//系数为0则直接返回该函数
if (q->data.expn == e.expn)//次数相等则系数相加
{
q->data.coef += e.coef;
return;
}
if (p && p->data.expn > e.expn)
{ //若比当前结点小,就插到当前结点的前面
o->data = e;
q->next = o;
o->next = p;
return;
}
//若比当前结点大,p指针不断后移,直至变为NULL跳出循环
//然后再插入链表,成为末尾结点
}
o->data = e;
q->next = o;
o->next = NULL;//临时节点的指针域指向null,成为末尾结点
}
void add(LinkList L1, LinkList L2, LinkList &L3)//多项式加法,结果以L3返回
{
L3 = (LinkList)malloc(sizeof(Lnode));//建立头结点
L3->next = NULL;
LinkList q = L1->next;//指向L1的头结点的下一节点
while (q)
{
Orderinsertmerge(L3, q->data);//插入至L3
q = q->next;
}
q = L2->next;//指向L2的头结点的下一节点
while (q)
{
Orderinsertmerge(L3, q->data);
q = q->next;
}
}
void mult(LinkList L1,LinkList L2,LinkList &L4)//多项式乘法,结果以L4返回
{
L4 = (LinkList)malloc(sizeof(Lnode));//建立头结点
L4->next = NULL;
term e;//储存相乘后的结果
LinkList p,q;
p=L1->next;//p指向L1的第一个结点
q=L2->next;//q指向L2的第一个结点
while(p)
{
while(q)
{
e.coef=p->data.coef*q->data.coef;//系数相乘
e.expn=p->data.expn+q->data.expn;//次数相加
Orderinsertmerge(L4, e);
q=q->next;
}
p=p->next;
q=L2->next;//q重新遍历L2
}
}
void printpolyn(LinkList p)//输出多项式
{
LinkList q = p->next;//从头结点的下一结点开始
while (q)
{
if (q->data.coef == 0)//如果系数为0,则不打印该项(加法会导致存在系数为零的项,不打印比删除方便)
{
q = q->next;
continue;
}
printf("%.0f", q->data.coef);//先输出系数
if (q->data.expn != 0)//如果次数不为零再输出,防止输出x^0
printf(" %d\n", q->data.expn);
q = q->next;//指向下一项
}
}
//--------------------------------------主函数区--------------------------------------
int main(){
LinkList L1, L2, L3,L4;
int n;scanf("%d", &n);
Creatpolyn(L1, n);
scanf("%d", &n);
Creatpolyn(L2, n);
add(L1, L2, L3);
mult(L1, L2, L4);
printf("\nL1+L2=\n");
printpolyn(L3);
printf("\nL1*L2=\n");
printpolyn(L4);
return 0;
}
将La和Lb合并成Lc,并输出Lc中奇数项的和sum
#include<bits/stdc++.h>
#define Status int
using namespace std;
typedef long long ll;
typedef int ElemType;
const int maxn=3000;
const ll INF=1e18;
/* typedef struct item
{
int expn;//定义数据域的数据类型
}ElemType; */
typedef struct Lnode//定义结点
{
ElemType data;//数据域
struct Lnode *next;//指针域
}LNode,*LinkList;//将这个类型命名为LNode,并定义一个指向这个类型的指针
void CreateList_L(LinkList &L,int n)//头插法
{ //逆位序输入n个元素的值,建立带表头结点的单链线性表L
L=(LinkList)malloc(sizeof(Lnode));
LinkList p;
L->next=NULL;//先建立一个带头结点的单链表
for(int i=n;i>0;--i)
{
p=(LinkList)malloc(sizeof(Lnode));//生成新结点
scanf("%d",&p->data);//输入元素值
p->next=L->next;L->next=p;//插入到表头
}
}
void creatlist(LinkList &L,int n)
{ //尾插法创建链表
L=(LinkList)malloc(sizeof(Lnode));
LinkList p,r=NULL;//它们的类型都是指针
L->next=NULL;
for(int i=0;i<n;++i)
{
p=(LinkList)malloc(sizeof(Lnode));
//强制类型转换是指针,大小是结构体
scanf("%d",&p->data);
p->next=NULL;
if(L->next==NULL) L->next=p;
else r->next=p;//链接新创建的结点
r=p;//r的指向在不断改变
}
}
Status GetElem_L(LinkList L,int i,ElemType &e)
{
//L是带头节点的单链表的头指针
//当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
LinkList p=L->next;int j=1;//初始化,p指向第一个结点,j为计数器
while(p&&j<i)
{ //顺指针向后查找,直到p指向第i个元素或p为空
p=p->next;++j;
}
if(!p||j>i)return 0;//遍历完发现第i个元素不存在
e=p->data;//取第i个元素
return 1;
}
Status ListInsert_L(LinkList&L,int i,ElemType e)
{ //前插法:在带头结点的单链线性表L中第i个位置之前插入元素e
LinkList p=L;int j=0;//P为头结点,j为计数器
LinkList s;
while(p&&j<i-1)
{ //寻找第i-1个结点
p=p->next;++j;
}
if(!p||j>i-1) return 0;//i<1或者大于表长加1
s=(LinkList)malloc(sizeof(Lnode));//生成指向新结点的指针
s->data=e;s->next=p->next;//插入L中
p->next=s;
return 1;
}
Status ListDelete_L(LinkList &L,int i,ElemType &e)
{ //在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
LinkList p=L;int j=0;
LinkList q; q=(LinkList)malloc(sizeof(Lnode));
while(p->next&&j<i-1)
{ //寻找第i个结点,并令p指向其前驱
p=p->next;++j;
}
if(!(p->next)||j>i-1) return 0;//删除位置不合理
q=p->next;p->next=q->next;//删除q结点,并释放
e=q->data;free(q);
return 1;
}
/* void MergeList_Sq(SqList LA,SqList LB,SqList &LC){
pa = LA.elem;
pb = LB.elem; //指针pa和pb的初值分别指向两个表的第一个元素
LC.length = LA.length+LB.length; //新表长度为待合并两表的长度之和
LC.elem = new ElemType[LC.length]; //为合并后的新表分配一个数组空间
pc = LC.elem; //指针pc指向新表的第一个元素
pa_last = LA.elem+LA.length-1; //指针pa_last指向LA表的最后一个元素
pb_last = LB.elem+LB.length-1; //指针pb_last指向LB表的最后一个元素
while(pa <= pa_last && pb <= pb_last){ //两个表都非空
if(*pa <= *pb) *pc++ = *pa++; //依次“摘取”两表中值较小的结点
else *pc++ = *pb++;
}
//此时a,b 之中一定有一个表为空
while(pb <= pb_last) *pc++ = *pb++; //LB表已到达表尾
while(pa <= pa_last) *pc++ = *pa++; //LA表已到达表尾
} */
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
//已知单链线性表La和Lb的元素按值非递减排列
//归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
LinkList pa,pb,pc;
pa=La->next; pb=Lb->next;
Lc=pc=La; //用La的头结点作为Lc的头结点
while(pa && pb){
if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next;}
else{pc->next=pb; pc=pb; pb=pb->next;}
}
pc->next=pa?pa:pb;//插入剩余段
//若pa不空,则pc->next = pa;,否则则为pc->next = pb;
free(Lb);//释放Lb的头结点
}
void List(LinkList L)
{ //打印链表
LinkList p;
int cnt=1,sum=0;
p=(LinkList)malloc(sizeof(Lnode));
/* if(L->data) p=L;//没有头结点的链表
else p=L->next;//有头结点的链表 */
p=L->next;
while(p)
{
printf("%d ",p->data);
if(cnt++%2==1) sum+=p->data;
p=p->next;
}
printf("\n%d\n",sum);
}
int main(){
LinkList La,Lb,Lc;
int n1,n2;
scanf("%d",&n1);
scanf("%d",&n2);
creatlist(La,n1);
//List(La);
creatlist(Lb,n2);
//List(Lb);
MergeList_L(La,Lb,Lc);
List(Lc);
return 0;
}
单链表的逆转求和
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define OVERFLOW -2
typedef int ElemType;
typedef int status;
typedef struct Lnode
{
ElemType data;
struct Lnode *next;
}Lnode,*linklist;
int sum=0;
status listcreate(linklist &L)
{
linklist p,endl;
int n;
L=(linklist)malloc(sizeof(Lnode));
if(!L)exit(OVERFLOW);
L->next=NULL;//链表的初始化
endl=L;
sum=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
p=(linklist)malloc(sizeof(Lnode));
if(!p) exit(OVERFLOW);
scanf("%d",&p->data);
sum+=p->data;
p->next=NULL;
endl->next=p;
endl=p;
}
return OK;//返回建立完成
}
void listoutput(linklist L)
{
L=L->next;
while(L)
{
printf("%d ",L->data);
L=L->next;
}
//return OK;
}
status reverse_list(linklist &L)
{
linklist p,q,s=NULL;
if(!L->next)return OK;//如果链表为空的话,直接返回
p=L->next;
q=p->next;
if(q) s=q->next;//如果q存在的话,s就指向q的下一个节点
p->next=NULL;
while(s)//跳出条件是s是否为空
{
q->next=p;
p=q;
q=s;
s=q->next;
}
if(q)
{
q->next=p;
L->next=q;
}
}
int main()
{
linklist L;
listcreate(L);
reverse_list(L);
listoutput(L);
printf("\n%d\n",sum);
return 0;
}