一元多项式表示及相加表示

1.(新手小白,总体代码写的比较繁琐,见谅,勿喷)

总体代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
//#include<vld.h>   用于检查内存泄漏

typedef struct listnode
{
	float data;                                                             //存放系数
	int cep;                                                                 //存放指数
	struct listnode* next;
}listnode,*linknode;
linknode creatlist();                                                        //创建空链表
linknode buynode();                                                          //购买节点
void printflist( linknode s);                                                //打印一元多项式
void insert_value(linknode s);                                               //插入数据
void push_back(linknode s);                                                  //尾插法
void push_front(linknode s);                                                 //头插法
void Freenode(linknode p);                                                   //释放内存
void clearlist(linknode s);                                                  //清空链表
void Destorylist(linknode s);                                                //摧毁链表
int capity(linknode s);                                                      //计算项数
void rever_list(linknode s);                                                 //顺序存放
void sort(int* b, int n);                                                    //排序
int findpos(int* a, int n, int b);                                           //查找下标
void download(linknode s, int n, int* a, float* b, int* c);                 //提取系数和项数
void Add(linknode a, linknode b);                                            //多项式合并
void brief_add(linknode a);                                                  //化简合并后的多项式
void clear_brieflist(linknode s);                                            //删除合并后的多项式的无用项
int clear_brieflist2(linknode s);
linknode buynode()
{
	listnode* s = (linknode)malloc(sizeof(listnode));
	if (NULL == s)  exit(1);
	memset(s, 0, sizeof(listnode));
	return s;
}
linknode creatlist()
{
	return buynode();
}
void printflist( linknode s)
{
	assert(s != NULL);
	linknode p = s->next;
	while (NULL != p)
	{
		if (p->data == 0) {
			p = p->next;
			continue;
		}
			printf("%.2lf(X)^%d", p->data, p->cep);
			if (p->next != NULL ) printf("+");
			p = p->next;
	}
	printf("\n");
}
void Freenode(linknode p)
{
	free(p);
	p = NULL;
}
void insert_value(linknode s)
{
		linknode cp =  buynode();
		scanf("%f,%d",& cp->data,& cp->cep);
		 cp->next =s->next;
		 s->next = cp; 
}
void push_back(linknode s)
{
	assert(NULL != s);
	while (NULL != s->next)
		s = s->next;
	insert_value(s);
}
void push_front(linknode s)
{
	assert(NULL != s);
	insert_value(s);
}
void clearlist(linknode s)
{
	assert(s != NULL);
	while (NULL != s->next)
	{
		linknode p;
		p = s->next;
		s->next = p->next;
		Freenode(p);
	}

}
void Destorylist(linknode s)
{
	clearlist(s);
	Freenode(s);
}
int capity(linknode s)
{
	assert(NULL != s);
	int n = 0;
	while (s->next != NULL)
	{
		n++;
		s = s->next;
	}
	return n;
}
void rever_list(linknode s)
{
	assert(NULL != s);
	int n = capity(s);
	int* a = (int*)malloc(sizeof(int) * n);                                         //顺序存放
	float* b = (float*)malloc(sizeof(float) * n);                                   //链表顺序 
	int* c = (int*)malloc(sizeof(int) * n);                                         //链表顺序  
	download(s, n,a,b,c);
	s = s->next;
	for(int i=0,j=0;i<n;i++)
	{ 
	  j = findpos(c, n, a[i]);                                                       //
	  s->data = b[j];
	  s->cep = a[i];
	  s =s->next;
	}
	free(a);
	free(b);
	free(c);
	a = NULL;
	b = NULL;
	c = NULL;
}
void sort(int* b, int n)
{
	assert(NULL != b);
	int temp;
	for (int i = 0; i < n-1; i++)
		for (int j = 0; j < n -1- i; j++)
			if (b[j] < b[j+1])
			{
				temp = b[j];
				b[j] = b[j+1];
				b[j+1] = temp;
			}
}
int findpos(int*a,int n, int b)
{
	assert(NULL != a);
	int i;
	for (i = 0; i < n ; i++)
	{
		if (a[i] == b)
		{
			a[i] = 0;
			return i;
		}
	}
}
void download(linknode s, int n,int* a,float* b,int* c)
{
	assert(NULL != s);
	linknode p = s->next;
	for (int i = 0; i < n; i++)
	{
		a[i] = p->cep;
		c[i] = p->cep;
		b[i] = p->data;
		p = p->next;
	}
	sort(a, n);
}

void Add(linknode a, linknode b)
{
	int n=0;
	assert(NULL != a && NULL != b);
	n = capity(a) + capity(b);
	
	while (a->next != NULL)	
		a=a->next;
		a->next = b->next;
		b->next = NULL;
		Freenode(b);
}
void brief_add(linknode a)
{
	int n = capity(a),i=0,j;
	linknode p = a->next;
	linknode q = a;
	float* b = (float*)malloc(sizeof(float) * n);
	int* c = (int*)malloc(sizeof(int) * n);
	while (a->next != NULL)
	{
		b[i] = a->next->data;
		c[i] = a->next->cep;
		a = a->next;
		i++;
	}
	
	for (i = 0 ; i < n; i++)
		for (j = i + 1; j < n; j++)
		{
			if (c[i] == c[j]) {
				b[i] += b[j];
				b[j] = 0;
			}
		}
	for (i = 0; i < n; i++)
	{
		 p->data = b[i];
		p= p->next;
	     
	}
	clear_brieflist(q);
	free(b);
	free(c);
}
void clear_brieflist(linknode s)
{
	assert(s != NULL);
	int i = 0;
	linknode p = s;
	while (NULL!=s->next)
	{
		s = s->next;
	}
	if (s->data == 0) {
		while (i <= clear_brieflist2(p))
			p = p -> next;
	}
	clearlist(p);
}
int clear_brieflist2(linknode s)
{
	assert(s != NULL);
	int i = 0,n=capity(s);
	float* a = (float*)malloc(sizeof(float) *n );
	while (NULL != s->next)
	{
		a[i] = s->next->data;
		s = s->next;
		i++;
	}
	for (i = n-1;; i--)
	{
		if (a[i] != 0) {
			free(a);
			return i;
		}
	}

}
int main()
{
	int n=0,m=0;
	listnode* a = creatlist();
	printf("请输入多项式a个数:");
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		printf("请输入多项式a第%d项的系数和指数:", i + 1);
		push_front(a);
	}
	printf("原一元多项式a为:");
	printflist(a);
	printf("排序后的一元多项式a为:");
	rever_list(a);
	printflist(a);
	listnode* b = creatlist();
	printf("请输入多项式b个数:");
	scanf("%d", &m);
	for (int i = 0; i < m; i++)
	{
		printf("请输入多项式b第%d项的系数和指数:", i + 1);
		push_back(b);
	}
	printf("原一元多项式b为:");
	printflist(b);
	printf("排序后的一元多项式b为:");
	rever_list(b);
	printflist(b);
	
	Add(a, b);
	printf("合并后的一元多项式b为:");
	printflist(a);
	rever_list(a);
	brief_add(a);
	printf("合并排序化简后的一元多项式b为:");
	printflist(a);
	Destorylist(a);
	return 0;
}

 注(main函数可自行设定)

1.结构体定义

typedef struct listnode
{
	float data;                                                             //存放系数
	int cep;                                                                 //存放指数
	struct listnode* next;
}listnode,*linknode;

注解:*linknode为指针,是指向lisinode类型的指针。

2.建立链表

linknode buynode()
{
	listnode* s = (linknode)malloc(sizeof(listnode));
	if (NULL == s)  exit(1);
	memset(s, 0, sizeof(listnode));
	return s;
}
linknode creatlist()
{
	return buynode();
}

定义linknode 型函数,内部动态申请内存。

3.输出链表 

void printflist( linknode s)
{
	assert(s != NULL);
	linknode p = s->next;
	while (NULL != p)
	{
		if (p->data == 0) {
			p = p->next;
			continue;                                             //防止无效项输出(系数为0)
		}
			printf("%.2lf(X)^%d", p->data, p->cep);
			if (p->next != NULL ) printf("+");
			p = p->next;
	}
	printf("\n");
}

4.插入函数(向链表里放入数据)

void insert_value(linknode s)
{
		linknode cp =  buynode();
		scanf("%f,%d",& cp->data,& cp->cep);
		 cp->next =s->next;
		 s->next = cp; 
}

原理图如下:先构建一个节点,进行插入(先断右链,再断左链,不然会造成数据丢失,无法找到下一节点地址。

 1.头插法

void push_front(linknode s)
{
	assert(NULL != s);
	insert_value(s);
}

 2.尾插法

void push_back(linknode s)
{
	assert(NULL != s);
	while (NULL != s->next)
		s = s->next;
	insert_value(s);
}

 5.清空链表

1.释放节点

void Freenode(linknode p)
{
	free(p);
	p = NULL;
}

2.无限头删法

void clearlist(linknode s)
{
	assert(s != NULL);
	while (NULL != s->next)
	{
		linknode p;
		p = s->next;
		s->next = p->next;
		Freenode(p);
	}

}

3.摧毁头节点

void Destorylist(linknode s)
{
	clearlist(s);
	Freenode(s);
}

6.计算数据个数(链表容量)

int capity(linknode s)
{
	assert(NULL != s);
	int n = 0;
	while (s->next != NULL)
	{
		n++;
		s = s->next;
	}
	return n;
}

 7.排序(更改链表数据域,使指数从高到底)

1.保存原链表的数据(用数组保存)

void download(linknode s, int n,int* a,float* b,int* c)
{
	assert(NULL != s);
	linknode p = s->next;
	for (int i = 0; i < n; i++)
	{
		a[i] = p->cep;
		c[i] = p->cep;
		b[i] = p->data;
		p = p->next;
	}
	sort(a, n);
}

2.排序(将指数进行排序)

void sort(int* b, int n)
{
	assert(NULL != b);
	int temp;
	for (int i = 0; i < n-1; i++)
		for (int j = 0; j < n -1- i; j++)
			if (b[j] < b[j+1])
			{
				temp = b[j];
				b[j] = b[j+1];
				b[j+1] = temp;
			}
}

 3.查找下标

int findpos(int*a,int n, int b)
{
	assert(NULL != a);
	int i;
	for (i = 0; i < n ; i++)
	{
		if (a[i] == b)
		{
			a[i] = 0;
			return i;
		}
	}
}

4. 重新给链表赋值,使其有序

void rever_list(linknode s)
{
	assert(NULL != s);
	int n = capity(s);
	int* a = (int*)malloc(sizeof(int) * n);                                         //顺序存放
	float* b = (float*)malloc(sizeof(float) * n);                                   //链表顺序 
	int* c = (int*)malloc(sizeof(int) * n);                                         //链表顺序  
	download(s, n,a,b,c);
	s = s->next;
	for(int i=0,j=0;i<n;i++)
	{ 
	  j = findpos(c, n, a[i]);                                                       //返回原链表指数的下标
	  s->data = b[j];
	  s->cep = a[i];
	  s =s->next;
	}
	free(a);
	free(b);
	free(c);
	a = NULL;
	b = NULL;
	c = NULL;
}

8.合并两个链表

合并方式如图


void Add(linknode a, linknode b)
{
	int n=0;
	assert(NULL != a && NULL != b);
	n = capity(a) + capity(b);
	
	while (a->next != NULL)	
		a=a->next;
		a->next = b->next;
		b->next = NULL;
		Freenode(b);
}

 9.化简合并后的链表

1.找到同类项(指数相同),将系数求和赋给第一个同类项,后续系数赋为0.

void brief_add(linknode a)
{
	int n = capity(a),i=0,j;
	linknode p = a->next;
	linknode q = a;
	float* b = (float*)malloc(sizeof(float) * n);
	int* c = (int*)malloc(sizeof(int) * n);
	while (a->next != NULL)
	{
		b[i] = a->next->data;
		c[i] = a->next->cep;
		a = a->next;
		i++;
	}
	
	for (i = 0 ; i < n; i++)
		for (j = i + 1; j < n; j++)
		{
			if (c[i] == c[j]) {
				b[i] += b[j];
				b[j] = 0;
			}
		}
	for (i = 0; i < n; i++)
	{
		 p->data = b[i];
		p= p->next;
	     
	}
	clear_brieflist(q);
	free(b);
	free(c);
}

2.判断尾结点数据域中系数是否0,并清除链表中无效节点(某一节点到尾结点的数据域中系数全为0)

void clear_brieflist(linknode s)
{
	assert(s != NULL);
	int i = 0;
	linknode p = s;
	while (NULL!=s->next)
	{
		s = s->next;
	}
	if (s->data == 0) {
		while (i <= clear_brieflist2(p))
			p = p -> next;
	}
	clearlist(p);
}

 3.找到链表中最后一个数据域中系数不为0的结点为几号。

int clear_brieflist2(linknode s)
{
	assert(s != NULL);
	int i = 0,n=capity(s);
	float* a = (float*)malloc(sizeof(float) *n );
	while (NULL != s->next)
	{
		a[i] = s->next->data;
		s = s->next;
		i++;
	}
	for (i = n-1;; i--)
	{
		if (a[i] != 0) {
			free(a);
			a=NULL;
			return i;
		}
	}

}

最后运行一下代码

可以看到代码正常运行,且无内存泄漏。 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值