链表的生成

利用链表实现一元多项式的+、-、*运算,注意具体的思路是判断同类项,对其进行合并同类项,在乘法运算达到了O(n^3),可以优化的地方是先对结果链表C进行预处理,先复制这个链表给C,然后表C的操作过程就将了一维,变成O(n^2),并且每次可以利用链表的有序性这一点进行二分,但这是链表啊!怎么二分?还没想到,干脆把链表先导入数组中,然后在操作?这样就O(nlogn)了?....扯远了,就先O(n^3)吧。

要求:

实验五、线性表应用—一元多项式加减运算

1 实验目的

掌握用线性结构表示一元多项式的方法及实现一元多项式的加、减运算。

实验内容

两个一元多项式从键盘输入,每一项主要包括系数和指数两个数据,分别将两个一元多项式存到两个单链表中,然后对两个一元多项式进行加、减运算,最后输出结果。

实验过程

1):

(截图

2) :

(截图

(3

(截图

 

源代码

(附件)

具体代码如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//******宏定义参数******
#define OK 1
#define NO 0
#define DATA_MAX_SIZE 20

//******定义数据类型别名******
typedef int Status;
typedef char Excelelem;
typedef int Numelem;
typedef double db;

//******声明数据结构******
typedef struct Node
{
	db xishu;
	db mi;
	struct Node *next;
}LNode,*LinkList;

typedef struct
{
	Excelelem name[100];
	Numelem length;
	LinkList next;
}HeadList,*HeadLinkList;

//******声明函数******
LinkList Init(Numelem *n); //初始化链表体
HeadLinkList HeadInit(char a[]); //初始化链表头
LinkList DATA_UPPER_FIND(LinkList Head,db ans); //查找链表中第一个系数大于ans的结点的前驱
void DATA_ADD(HeadLinkList A,HeadLinkList B,HeadLinkList C); //多项式加法 O(n)
void DATA_SUB(HeadLinkList A,HeadLinkList B,HeadLinkList C); //多项式减法 O(n)
void DATA_Free(HeadLinkList Head); //释放链表体内存
void DATA_cout(HeadLinkList Head); //将链表数据域以多项式形势输出
void DATA_MUL(HeadLinkList A,HeadLinkList B,HeadLinkList C); //多项式乘法 O(n^3)

int main()
{
	HeadLinkList A,B,C;
	Numelem n;
	printf("**********start!**********\n");
	A=HeadInit("A多项式");
	printf("请输入%s:\n",A->name);
	A->next=Init(&A->length);
	B=HeadInit("B多项式");
	printf("请输入%s:\n",B->name);
	B->next=Init(&B->length);
	C=HeadInit("C多项式");
	C->next=NULL;
	printf("请输出%s的内容:\n",A->name);
	DATA_cout(A);
	printf("请输出%s的内容\n",B->name);
	DATA_cout(B);
	printf("%s+%s:\n",A->name,B->name);
	DATA_ADD(A,B,C);
	DATA_cout(C);
	printf("%s-%s:\n",A->name,B->name);
	DATA_SUB(A,B,C);
	DATA_cout(C);
	printf("%s*%s:\n",A->name,B->name);
	DATA_MUL(A,B,C);
	DATA_cout(C);
	printf("操作结束,释放内存!\n");
	DATA_Free(A);DATA_Free(B);DATA_Free(C);
	free(A),free(B),free(C);
	printf("***********End!***********\n");
	return 0;
}

//******查找插入的位置******
LinkList DATA_UPPER_FIND(LinkList Head,db ans)
{
	if(Head->next == NULL || Head->next->mi > ans)
		return Head;
	return DATA_UPPER_FIND(Head->next,ans);
}

LinkList Init(Numelem *n)
{
	//以系数=0为输入结束标志,以下为输入的多项式默认为已合并同类项,否则在查找的时候多一项特判
	LinkList Head,p,q;
	Numelem i=0;
	db a,b;
	Head=NULL;
	while(~scanf("%lf",&a) && a!=0.0)
	{
		scanf("%lf",&b);
		q=(LinkList)malloc(sizeof(LNode));
		q->xishu=a;
		q->mi=b;
		if(*n==0 || Head->mi>b) q->next=Head,Head=q;
		else
		{
			p=DATA_UPPER_FIND(Head,b);
			//if p->mi==b ...  未合并同类项的情况
			q->next=p->next;
			p->next=q;
		}
		*n++;
	}
	return Head;
}

HeadLinkList HeadInit(char *a)
{
	HeadLinkList Head;
	Head=(HeadLinkList)malloc(sizeof(HeadList));
	strcpy(Head->name,a);
	Head->length=0;
	return Head;
}

void DATA_ADD(HeadLinkList A,HeadLinkList B,HeadLinkList C)
{
	LinkList qa=A->next,qb=B->next,p,q=NULL;
	DATA_Free(C);
	while(qa || qb)
	{
		p=(LinkList)malloc(sizeof(LNode));
		if(qb==NULL || qa && qa->mi<qb->mi)
		{
			*p=*qa;
			qa=qa->next;
		}
		else if(qa==NULL || qb && qa->mi>qb->mi)
		{
			*p=*qb;
			qb=qb->next;
		}
		else
		{
			p->xishu=qb->xishu+qa->xishu;
			p->mi=qb->mi;
			qa=qa->next;
			qb=qb->next;
		}
		if(q==NULL) p->next=q,C->next=q=p;
		else
			p->next=q->next,q->next=p,q=p;
		C->length++;
	}
}

void DATA_SUB(HeadLinkList A,HeadLinkList B,HeadLinkList C)
{
	LinkList qa=A->next,qb=B->next,p,q=NULL;
	DATA_Free(C);
	while(qa!=NULL || qb!=NULL)
	{
		p=(LinkList)malloc(sizeof(LNode));
		if(qb==NULL || qa && qa->mi<qb->mi)
		{
			*p=*qa;
			qa=qa->next;
		}
		else if(qa==NULL || qb && qa->mi>qb->mi)
		{
			*p=*qb;
			p->xishu*=-1;
			qb=qb->next;
		}
		else
		{
			*p=*qa;
			p->xishu-=qb->xishu;
			qa=qa->next;
			qb=qb->next;
			if(p->xishu==0)
			{
				free(p);
				continue;
			}
		}
		if(q==NULL) p->next=q,C->next=q=p;
		else
			q->next=p->next,q->next=p,q=p;
		C->length++;
	}
}

void DATA_MUL(HeadLinkList A,HeadLinkList B,HeadLinkList C)
{
	LinkList qa,qb,p,q;
	db a,b;
	DATA_Free(C);
	for(qa=A->next;qa;qa=qa->next)
	{
		for(qb=B->next;qb;qb=qb->next)
		{
			a=qa->xishu*qb->xishu;
			b=qa->mi+qb->mi;
			if(C->length)
			{
				p=DATA_UPPER_FIND(C->next,b);
				if(p->mi == b)
					p->xishu+=a;
				else
				{
					q=(LinkList)malloc(sizeof(LNode));
					q->xishu=a;
					q->mi=b;
					q->next=p->next;
					p->next=q;
					C->length++;
				}
			}
			else
			{
				p=(LinkList)malloc(sizeof(LNode));
				p->xishu=a;
				p->mi=b;
				p->next=C->next;
				C->next=p;
				C->length++;
			}
		}
	}
}

void DATA_Free(HeadLinkList Head)
{
	LinkList q=Head->next,p;
	while (q)
	{
		p=q;
		q=q->next;
		free(p);
	}
	Head->length=0;
	Head->next=NULL;
	return ;
}

void DATA_cout(HeadLinkList Head)
{
	LinkList q=Head->next;
	while(q)
	{
		if(q->xishu>0 && q!=Head->next)
			printf("+");
		printf("%.1lfx^(%.1lf)",q->xishu,q->mi);
		q=q->next;
	}
	printf("\n");
	return ;
}

总结:

链表和顺序表的直接操作各有优点,在处理离散程度较大的数据时,链表可以节省空间,顺序表就会比较耗内存;在处理相对连续的数据时,用到顺序表就可以利用其逻辑结构和物理结构一直这一特点,降低算法的复杂度。