一元多项式计算
分析题目
两种存储方法:
- 只存储各项系数,存储位置下标就可以对应指数值,适用于非零项系数多的(也就是不稀疏)
- 系数和指数均存入顺序表,适用于零项很多,指数较大(一个一个算指数太慢)
结点结构
多项式<--->polynomial
typedef struct Polynode{
int coef; //系数
int exp; //指数
struct Node *next;
}Polynode,*Polylist;
创建一元多项式
采用尾插法依次插入系数和指数,思想不再赘述
Polylist CreatPoly(){ //尾插法,多项式创建函数
Polynode *head,*rear,*s;
int a,b; //分别为系数和指数
head=(Polynode*)malloc(sizeof(Polynode)); //申请一个头结点
rear=head; //尾结点连上头结点
printf("输入系数和指数,逗号分隔,系数输入“99999”结束输入\n");
scanf("%d,%d",&a,&b); //首次输入,a为系数,b为指数
while(a!=99999) //当系数为99999时结束输入多项式
{
s=(Polynode*)malloc(sizeof(Polynode));
s->coef=a;
s->exp=b;
rear->next=s; //尾指针指向新结点
rear=s;
scanf("%d,%d",&a,&b);
}
rear->next=NULL; //尾结点指向NULL
return head; //返回头结点即可
}
主体解读:首先输入两个值并判断是否结束,不结束的话就进入while循环,每次循环都重新赋值并检测是否结束。
两式相加
所加两式默认升幂排列(也可以冒泡排序成升幂)
- p指向LA,q指向LB
- 以LA为“和多项式”
- 若p结点指数较小,则p后移
- 若q结点指数较小,则q插入在p之前
- 若p结点和q结点指数相同,则将系数相加。 和不为0时修改p结点,释放q结点;为0时删除p结点,释放p和q
最重要需要注意多次给tail->next赋值
#include<stdio.h>
#include<stdlib.h>
typedef struct Polynode{
int coef; //系数
int exp; //指数
struct Polynode *next;
}Polynode,*Polylist;
Polylist CreatPoly(); //多项式创建函数
Polylist AddPoly(Polylist LA,Polylist LB); //将LA和lB两个多项式相加
int main(){
Polylist LA,LB;
Polynode *p;
printf("输入第一个多项式\n");
LA=CreatPoly();
printf("\n输入第二个多项式\n");
LB=CreatPoly();
printf("\n\n两式输入结束\n\n");
AddPoly(LA,LB);
printf("\n");
p=LA->next;
while(p!=NULL){
printf("%d,%d ",p->coef,p->exp);
p=p->next;
}
}
Polylist CreatPoly(){ //尾插法,多项式创建函数
Polynode *head,*rear,*s;
int a,b; //分别为系数和指数
head=(Polynode*)malloc(sizeof(Polynode)); //申请一个头结点
rear=head; //尾结点连上头结点
printf("输入系数和指数,空格分隔,系数输入“999”结束输入\n");
scanf("%d %d",&a,&b); //首次输入,a为系数,b为指数
while(a!=999) //当系数为99999时结束输入多项式
{
s=(Polynode*)malloc(sizeof(Polynode));
s->coef=a;
s->exp=b;
rear->next=s; //尾指针指向新结点
rear=s;
scanf("%d %d",&a,&b);
}
rear->next=NULL; //尾结点指向NULL
return head; //返回头结点即可
}
Polylist AddPoly(Polylist LA,Polylist LB){ //将LA和lB两个多项式相加
Polynode *p,*q,*tail,*temp;
//tail是“和多项式”的表尾指示器,temp是临时结点
int sum; //系数和
p=LA->next; //指向首元
q=LB->next;
while(p!=NULL&&q!=NULL) //都没处理完
{
/*每次都需要重新定位tail,因为系数和为0时候,tail所指结点会被销毁*/
if(p->exp<q->exp)
{
tail->next=p; //定位tail
tail=p; //表尾跟上p
p=p->next; //p后移
printf("下一个");
}
else if(p->exp==q->exp)
{
sum=p->coef+q->coef;
if(sum!=0)
{
p->coef=sum; //修改数值
tail->next=p; //定位tail
tail=p; //表尾跟上p
p=p->next; //p后移
temp=q; //需要释放q但不能丢了q
q=q->next; //q全身而退
free(temp); //temp成了替死鬼
printf("取代");
}
else //将p和q所指结点删除
{
temp=p;
p=p->next;
free(temp);
temp=q;
q=q->next;
free(temp);
printf("双效");
}
}
else if(p->exp>q->exp)
{
tail->next=q;
tail=q;
q=q->next;
printf("接上");
}
if(p!=NULL)
{
tail->next=p;
}
else
{
tail->next=q;
}
}
printf("加法运算完毕");
}
主体解读:本算法最后将“和多项式”在LA中体现。 若p结点指数较小,则tail跟上p,p后移;若两结点指数相同,;
若q结点指数较小,则q插入在p之前,让tail跟上q
若p结点和q结点指数相同,则将系数相加。 和不为0时修改p结点,释放q结点;为0时删除p结点,释放p和q
原地逆置单链表
所以我们需要将原链表在原有空间中,使用头插法
void ReverseList(LinkList L)
{
p=L->next; //定位首元结点
L->next=NULL; //断掉头结点与原表关系
while(p!=NULL)
{
q=p->next; //保留技术
p->next=L->next;
L->next=p;
p=q;
}
}
二进制数加1
分析:
耿国华老师:
www.bilibili.com/video/BV1kx…