1.多项式乘法实现

对于稀疏多项式,采用数组存储效率低下,因此考虑采用链表结构,节点包括系数,指数,next指针三个域。多项式的运算中,主要要考虑的是同类项合并的问题,这实际是一个数组元素去重的问题(合并幂相同的节点),因此可以采用先排序(快排平均O(Nlog(N))),后遍历(O(N))的方式完成。总时间O(nlog(n))。

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

typedef struct node {
	int coef;
	int exponent;
	struct node* next;
}node;

typedef struct List {
	node* next;
}List;

//打印多项式
void print_poly(List* poly)
{
	node* p = poly->next;
	while (p != NULL)
	{
		printf("%d*x^%d + ", p->coef,p->exponent);
		p = p->next;
	}
	printf("\n");
}

//创建空表
List* make_empty()
{
	List* list = (List*)malloc(sizeof(List));
	list->next = NULL;
	return list;
}

//在链表p节点后插入一个节点
void insert_node(List* list, node* p,int coef,int exponent)
{
	if (list == NULL)
		return;
	node* p_new = (node*)malloc(sizeof(node));
	p_new->coef = coef;
	p_new->exponent = exponent;
	if (p == NULL)//在头部插入
	{
		p_new->next = list->next;
		list->next = p_new;	
	}
	else
	{
		p_new->next = p->next;
		p->next = p_new;
	}
}


//获取链表长度
int length(List* list)
{
	int len = 0;
	node* pCur = list->next;
	while (pCur != NULL)
	{
		++len;
	}
	return len;
}

//获取尾部节点
node* last_node(List* list)
{
	node* p_node = list->next;
	while (p_node->next != NULL)
	{
		p_node = p_node->next;
	}
	return p_node;
}
//交换两节点内容
void swap_node(node* n1,node* n2)
{
	int tmp_coef = n1->coef;
	int tmp_exponent = n1->exponent;
	n1->coef = n2->coef;
	n1->exponent = n2->exponent;
	n2->coef = tmp_coef;
	n2->exponent = tmp_exponent;
}
//快速排序的分割,随机选取一个基准,把小于它的放到前面,大于的放到后面
node* partition(node* start, node* end)
{
	//取第一个数作为基准数,这其实有问题,当为有序数组时速度很慢,应当选(start+end)/2位置的数,保证一定的随机性
	node* p = start;
	node* q = p->next;	//q比p初始快一步
	node* reference = start;	//基准
	//从start开始向后进行一次遍历(单链表无法从后向前)
	while (/*q != NULL &&*/ q != end->next)
	{
		if (q->exponent < reference->exponent)
		{
			p = p->next;	//p永远指向的是当前已遍历过且比基准数小的最后一个数
			swap_node(p, q);
		}
		q = q->next;
	}
	swap_node(p, reference);	//最后将位于头部的基准与p交换,完成当前段的分割
	return p;
}

void quick_sort(node* start,node* end)
{
	if (start == end || start == NULL || end == NULL) //这个停止条件要注意必须保证start和end非空
	{
		return;
	}
	node* mid = partition(start, end);

	quick_sort(start, mid);
	quick_sort(mid->next, end);
}
//链表多项式的排序,同时合并指数相同的项
void sort_list(List* list)	
{
	if ((list->next == NULL) || (list->next->next == NULL))
	{
		return;
	}
	node* start = list->next;
	node* end = last_node(list);
	quick_sort(start, end);	
}

//多项式乘法返回一个新多项式链表
List* mult_polynomial(List* list_in1, List* list_in2)	
{
	//先准备好新的多项式链表的大小
	List* prod = make_empty();
	node* p_node_in1 = list_in1->next;
	node* p_node_in2 = list_in2->next;

	int prod_exponent = 0;
	int prod_coef = 0;

	while (p_node_in1 != NULL)
	{
		p_node_in2 = list_in2->next;	//这里记住要及时返回
		while (p_node_in2 != NULL)
		{
			prod_coef = p_node_in1->coef * p_node_in2->coef;
			prod_exponent = p_node_in1->exponent + p_node_in2->exponent;
			insert_node(prod, NULL, prod_coef, prod_exponent);	//每次都在头部插入

			p_node_in2 = p_node_in2->next;
		}
		p_node_in1 = p_node_in1->next;
	}

	//链表排序
	sort_list(prod);

	//合并同类项
	node* pCur = prod->next;
	node* pDelete = NULL;
	int i = 0;
	while (pCur->next != NULL)
	{
		if (pCur->exponent == pCur->next->exponent)
		{
			pCur->coef += pCur->next->coef;
			//删除多余节点
			pDelete = pCur->next;
			pCur->next = pDelete->next;
			free(pDelete);
			pDelete = NULL;
			continue;	//这个很关键,因为这里的if中修改了节点的next的指向,因此pCur就不能进行步进,而应当停留原地
		}
		pCur = pCur->next;
	}
	return prod;
}

int main()
{
	List* poly1 = (List*)malloc(sizeof(List));
	List* poly2 = (List*)malloc(sizeof(List));

	node* x1 = (node*)malloc(sizeof(node));
	x1->coef = 3; x1->exponent = 7;	//3x^3

	node* x2 = (node*)malloc(sizeof(node));
	x2->coef = 5; x2->exponent = 12;	//5x^1

	node* x3 = (node*)malloc(sizeof(node));
	x3->coef = 2; x3->exponent = 15;	//2x^6

	node* x4 = (node*)malloc(sizeof(node));
	x4->coef = 9; x4->exponent = 6;	//9x^6



	x1->next = x2;
	x2->next = x3;
	x3->next = x4;
	x4->next = NULL;
	poly1->next = x1;

	node* y1 = (node*)malloc(sizeof(node));
	y1->coef = 4; y1->exponent = 7;	//4x^2

	node* y2 = (node*)malloc(sizeof(node));
	y2->coef = 1; y2->exponent = 6;	//1x^5

	node* y3 = (node*)malloc(sizeof(node));
	y3->coef = 3; y3->exponent = 12;	//3x^4

	node* y4 = (node*)malloc(sizeof(node));
	y4->coef = 7; y4->exponent = 5;	//7x^5


	y1->next = y2;	
	y2->next = y3; 
	y3->next = y4;
	y4->next = NULL;
	poly2->next = y1;

	sort_list(poly1);
	sort_list(poly2);

	print_poly(poly1);
	print_poly(poly2);
	List* prod = mult_polynomial(poly1, poly2);
	print_poly(prod);

	return 0;
}

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值