一元多项式的运算 单链表实现

前言 

        实现将两个多项式相加、相减、相乘。具体代码以及讲解在下方。


1.引入库

  1. stdio.h:提供输入输出操作相关的函数,如printf、scanf等。
  2. stdlib.h:提供内存管理、类型转换、随机数生成等功能,如malloc、free、atoi等。
  3. math.h:提供数学运算相关的函数,如sin、cos、sqrt等。
#include <stdio.h>
#include <stdlib.h>
#include <math.h> 

2结构体定义

        数据域包含data和datax,data表示系数,datax表示指数

typedef struct Lnode{
	int data;        //系数
	int datax;        //指数
	struct Lnode* next;
}LNode,*LinkList;

3.链表初始化

        单链表包含头节点,方便后续插入操作 

LinkList InitList(LinkList L){//头结点 
	L=(LinkList)malloc(sizeof(LNode));
	if(L==NULL)
		exit(EXIT_FAILURE);
	L->next=NULL;
	return L;
}

4.读入数据

        读入数据,要实现对输入的数据自行进行排序,即使在输入时指数没有按照由小到大的数据顺序,也能按照由小到大的顺序输出。

        在createList函数中,通过尾插法,将输入的结点添加到已经初始化好的单链表中,并通过LocateElem函数实现对输入的数据进行排序。

         LocateElem函数讲解:

                 L是之前的链表,p是要插入的结点,在while循环中遍历L,分成三种请况

                1.如果p的指数比L的第一项大,则继续向后遍历

                2.如果p的指数与L的某一项相等,则将系数合并,跳出循环,尾指针r不变,因为最下面的if语句不会被执行。

                3.如果p的指数比L的第一项小,则将p插入到L的某一项的前面,尾指针r不变,因为最下面的if语句不会被执行。

        最下面的if语句,只有当p的指数比L中的每一项的指数都大时才会执行。

void createList(LinkList L,int l1){
	int i;
	LinkList p,r=L;//p是要插入的结点,r是尾指针
	for(i=0;i<l1;i++){//尾插法
		p=(LinkList)malloc(sizeof(LNode));
		printf("请输入第%d项的系数和指数(以空格隔开):",i+1);
		scanf("%d%d",&p->data,&p->datax);
		r=LocateElem(L,p,r);
	}
}
LinkList LocateElem(LinkList L,LinkList p,LinkList r){//排序
	LinkList p1=L->next,p2=L;//p2为p1的前一项
	while(p1){
		if(p->datax>p1->datax){
			p1=p1->next;
			p2=p2->next;
		}
		else if(p->datax==p1->datax){
			p1->data=p1->data+p->data;
			break;
		}
		else{
			p2->next=p;
			p->next=p1;
			break;
		}
	}
	if(!p1){    //p1==NULL
		p->next=NULL;
		r->next=p;
		r=p;
		return r;
	}
}

5.相加操作

        为保证相加后的多相似依旧有序,需对相加的两项进行判断,分为三种情况。

         从第一项开始,如果L1的指数小于L2的指数 ,则将L1的第一项添加到L3中,L1指向它的下一项,L2不动。

        如果L1的指数等于L2的指数,则将这两项合并后添加到L3中,L1和L2都指向下一项。

        如果L1的指数大于L2的指数 ,则将L2的第一项添加到L3中,L2指向它的下一项,L1不动。

        直到L1或L2完全遍历完为止,然后将L1或L2中没有遍历完的部分(较长的)添加L3中。

void AdditionList(LinkList L1,LinkList L2,LinkList L3){
	LinkList p=L1->next,q=L2->next,s,sr=L3;
	while(p&&q){
		s=(LinkList)malloc(sizeof(LNode)); 
		if(p->datax<q->datax){//L1的指数比L2小 
			s->data=p->data;
			s->datax=p->datax;
			s->next=NULL;
			sr->next=s;
			sr=s;
			p=p->next; 
		}
		else if(p->datax==q->datax){//L1的指数和L2相等
			s->data=p->data+q->data;
			s->datax=p->datax;
			s->next=NULL;
			sr->next=s;
			sr=s;
			p=p->next;
			q=q->next; 
		}
		else{//L1的指数比L2大 
			s->data=q->data;
			s->datax=q->datax;
			s->next=NULL;
			sr->next=s;
			sr=s;
			q=q->next; 
		}
	}
	if(p){
		s->next=p;
	}
	else{
		s->next=q; 
	}
}

6.相减操作

        相减操作和相加操作的算法一样,只不过在相减操作中需要先将第二个多项式的系数变成负的,再进行操作。

         此时会产生一个问题,就是L2中data域的值全都取负了,在执行时如果先进行了相减操作,会使之后进行的相加相乘操作产生错误。

void SubtractList(LinkList L1,LinkList L2,LinkList L4){
	LinkList p=L1->next,q=L2->next,s,sr=L4;
	while(q){//找负 
		q->data=0-(q->data);
		q=q->next;
	}
	q=L2->next;
	while(p&&q){
		s=(LinkList)malloc(sizeof(LNode)); 
		if(p->datax<q->datax){//L1的指数比L2小 
			s->data=p->data;
			s->datax=p->datax;
			s->next=NULL;
			sr->next=s;
			sr=s;
			p=p->next; 
		}
		else if(p->datax==q->datax){//L1的指数和L2相等
			s->data=p->data+q->data;
			s->datax=p->datax;
			s->next=NULL;
			sr->next=s;
			sr=s;
			p=p->next;
			q=q->next; 
		}
		else{//L1的指数比L2大 
			s->data=q->data;
			s->datax=q->datax;
			s->next=NULL;
			sr->next=s;
			sr=s;
			q=q->next; 
		}
	}
	if(p){
		s->next=p;
	}
	else{
		s->next=q; 
	}
}

7.相乘操作

        f(x1)=2X^2+3X^3,f(x2)= 3X^2+4X^3

         对于上面两个多项式,相乘时,结果多项式会有三项而非四项。因有两项发生了合并。结局办法是将第一个多项式的第一项拿出来,依次和第二个多项式的每一项相乘,此时的操作和读入数据是完全相同的。

void multiplyList(LinkList L1,LinkList L2,LinkList L5){
	LinkList p=L1->next,q=L2->next,r=L5,p1;
	for(;p;){
		for(;q;){
			p1=(LinkList)malloc(sizeof(LNode));
			p1->data=p->data*q->data;
			p1->datax=p->datax+q->datax;
            r=LocateElem(L5,p1,r);
			q=q->next;
		}
		p=p->next;
		q=L2->next;
	}
}

8.打印多项式

void printfList(LinkList L,int j){
	LinkList p=L->next;
	if(j==3){
		printf("和多项式为:P(X)=");
	} 
	else if(j==4){
		printf("差多项式为:P(X)=");
	}
	else if(j==5){
		printf("积多项式为:P(X)=");
	}
	else{
		printf("第%d个多项式为:P(X)=",j);
	}
	while(p){
		if(p->data!=0){
			printf("%dX^%d",p->data,p->datax);
			p=p->next;
			if(p!=NULL){//不是最后一项
				if(p->data>=0){//系数是整数
				printf("+");
				}
			}
		} 
		else if(p->data==0&&p->next==NULL){//首项为0,且只有一项
			printf("0");
			p=p->next;
		}
		else{
			p=p->next;	
		}
	}
	printf("\n");	
}

9.多项式带值计算

void Sum(LinkList L,int x){
	int i=0;
	LinkList p=L->next; 
	while(p){
		i+=p->data*pow(x,p->datax);
		p=p->next;
	}
	printf("结果为:%d\n",i);
}

10.销毁单链表

void Destory(LinkList* L){
	LinkList p;
	while(*L){
		p=*L;
		*L=(*L)->next; 
		free(p);
	}
}

11.菜单

void menu(){
	printf( "*******************************************************\n");
	printf( "****************    1.输入1   相加  *******************\n");
	printf( "****************    2.输入2   相减  *******************\n");
	printf( "****************    3.输入3   相乘  *******************\n");
	printf( "****************    4.输入4   退出	 *******************\n");
	printf( "*******************************************************\n");
}

12.主函数

int main(int argc, char *argv[])
{
	char p,c;
	int l1,l2,x,y;
	LinkList L1,L2,L3,L4,L5;
	L1=InitList(L1);//第一个多项式
	L2=InitList(L2);//第二个多项式
	L3=InitList(L3);//相加后的多项式
	L4=InitList(L4);//相减后的多项式
	L5=InitList(L5);//相乘后的多项式
	printf("请输入第一个多项式的项数:");
	scanf("%d",&l1);
	createList(L1,l1);
	printfList(L1,1);
	printf("请输入第二个多项式的项数:");
	scanf("%d",&l2);
	createList(L2,l2);
	printfList(L2,2);
	menu();
	while ((c = getchar()) != '\n' && c != EOF){
	 // 清空输入缓冲区中的其他字符
	}
	printf("请输入要进行的操作序号:"); 
 	while(scanf("%d",&y)){
	 	if(y==4){
	 		printf("再见\n");
	 		Destory(&L1);
			Destory(&L2);
			Destory(&L3);
			Destory(&L4);
			Destory(&L5);
			return 0;	
	 	}
	 	switch(y){
	 		case 1:
	 			AdditionList(L1,L2,L3);//相加 
				printfList(L3,3);
				printf("是否带入X求结果?(是:Y,否:N):");
				scanf(" %c",&p);
				if(p=='Y'||p=='y'){
					printf("请输入X的值:");
					scanf("%d",&x);
					Sum(L3,x);
				}
				printf("请输入要进行的操作序号:");
	 			break;
	 		case 2:
		 		SubtractList(L1,L2,L4);//相减 
				printfList(L4,4);
				printf("是否带入X求结果?(是:Y,否:N):");
				scanf(" %c",&p);
				if(p=='Y'||p=='y'){
					printf("请输入X的值:");
					scanf("%d",&x);
					Sum(L4,x);
				}
				printf("请输入要进行的操作序号:");
	 			break;
			case 3:
				multiplyList(L1,L2,L5);//相乘 
				printfList(L5,5);
				printf("是否带入X求结果?(是:Y,否:N):");
				scanf(" %c",&p);
				if(p=='Y'||p=='y'){
					printf("请输入X的值:");
					scanf("%d",&x);
					Sum(L5,x);
				}
				printf("请输入要进行的操作序号:");
		 		break;
	 		default:
	 			printf("输入有误请重新输入\n");
			 	printf("请输入要进行的操作序号:");
	 			break;
		}
	 }
}

运行示例

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java基于单链表存储结构的一元多项式求和运算可以通过以下步骤实现: 1. 定义一个节点类,包含三个属性:系数(coefficient)、指数(exponent)和下一个节点(next)的地址。 2. 定义一个单链表类,包含一个头节点(head)。 3. 创建两个一元多项式单链表对象,分别存储两个多项式。 4. 对两个多项式的单链表进行遍历,将同一指数的项相加,并将结果存入一个新的单链表中。 5. 返回结果单链表对象。 具体实现可以参考以下Java代码: ``` public class Node { public double coefficient; // 系数 public int exponent; // 指数 public Node next; // 下一个节点的地址 public Node(double coefficient, int exponent) { this.coefficient = coefficient; this.exponent = exponent; this.next = null; } } public class LinkedList { public Node head; // 头节点 public LinkedList() { this.head = new Node(0, 0); // 创建头节点 } // 添加节点 public void addNode(double coefficient, int exponent) { Node node = new Node(coefficient, exponent); Node p = head; while (p.next != null && p.next.exponent > exponent) { p = p.next; } if (p.next != null && p.next.exponent == exponent) { p.next.coefficient += coefficient; } else { node.next = p.next; p.next = node; } } // 多项式求和 public LinkedList add(LinkedList list) { LinkedList result = new LinkedList(); Node p1 = this.head.next; Node p2 = list.head.next; while (p1 != null && p2 != null) { if (p1.exponent > p2.exponent) { result.addNode(p1.coefficient, p1.exponent); p1 = p1.next; } else if (p1.exponent < p2.exponent) { result.addNode(p2.coefficient, p2.exponent); p2 = p2.next; } else { double coefficient = p1.coefficient + p2.coefficient; if (coefficient != 0) { result.addNode(coefficient, p1.exponent); } p1 = p1.next; p2 = p2.next; } } while (p1 != null) { result.addNode(p1.coefficient, p1.exponent); p1 = p1.next; } while (p2 != null) { result.addNode(p2.coefficient, p2.exponent); p2 = p2.next; } return result; } } ``` 使用时,可以先创建两个多项式的单链表对象,然后调用add方法求和,最后遍历结果单链表输出即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值