使用链表进行多项式加乘法运算

一、程序任务

  1. 设计构造两个链式线性表,用来表示两个一元多项式
  2. 程序允许用户手工输入这两个线性表,每个线性表中的每个数据元素包含两个值,系数Pi和幂qi;输入方式自定;
  3. 程序对两个多项式进行相加,然后输出一个相加后的一元多项式。
  4. 两个多项式相乘

二、编程思路

【创建链表】先分别输入两个多项式的项数以及调用Createlist()函数按降幂顺序输入各项的系数和次数,构建出两个多项式的链表。两个多项式的系数和次数同样按降幂顺序存入两个线性表a、b,头结点分别为head_a,head_b

 

【多项式相加】创建一个新链表,作为相加后所得结果的多项式的链表寄存处。定义两个临时链表节点指针pa和pb,分别指向两个链表头结点的下一位(注:链表的头结点不存项)通过比较两个多项式的首项确定最高次幂,用max_qi记录。然后用一个for循环从两个链表中寻找,判断pa和pb当前位置有无次数为i(i为循环变量)的项,有则合并同类项。如果pa、pb次数等于i,两对应系数相加,和其系数一起存入新节点中,再将新节点插入新链表中,pa、pb随后后移一个单位;如果pa的次数小于i,pb次数等于i,只加pb项,也存入新节点并插入新链表中,随后pb向后移动一个单位如果pb的次数小于i,pa次数等于i,处理方法与上一种情况类似。如果pa和pb次数均小于i,则i减小1,进入下一次循环,再作比较。若pa或pb为空,则将不为空的多项式链表的剩余项逐一赋给新链表即可。

 

【多项式相乘】创建一个新链表,作为相乘后所得结果的多项式的链表寄存处。定义两个临时链表节点指针pa和pb,分别指向两个链表头结点的下一位通过将两个多项式的首项次数相加确定乘积的最高次幂,用qi_max记录。将链表b(pb所指链表)倒置,使b链表各项按升序排列。然后用一个for循环从两个链表中按顺序逐一寻找各项指数,看其两项的指数和是否等于循环变量k。若相等,则将两者系数相乘,加入变量pi(初始时为0)中,然后pa、pb各自后移一个单位,再判断指数和是否为k。若指数和小于k,则pb往后移一个单位,再判断;若指数和大于k,则pa往后移一个单位,再判断。直到pa或pb为空,结束指数和的大小判断。若pi不为0,说明次数为k的项系数不为0,则构造新节点,存入次数、系数,并插入新链表中。然后,k减小1,进入下一次循环。执行for循环直到k=0。得到结果后又将链表b倒置,恢复原来的降幂排序。

 

【多项式输出】利用while循环遍历链表,输出每一项,直到尾部。

三、关键代码

【主函数】

int main()  
{     
   
    int n;  
    cout<<"请输入A(X)的项数(按降幂排列)\n";  
    cin>>n; 
    listnode *head_a=CreateList(n);  
    cout<<"A(X)=";  
    printflist(head_a);  
    cout<<"请输入B(X)的项数(按降幂排列)\n";  
    cin>>n; 
    listnode *head_b=CreateList(n);  
    cout<<"B(X)=";  
    printflist(head_b);

	listnode *head_c=MultiplyPoly(head_a,head_b);
	cout<<"多项式相乘:"<<endl;
    cout<<"C(X)=A(X)*B(X)=";  
    printflist(head_c);  

	listnode *head_d=AddPoly(head_a,head_b);  
	cout<<"多项式相加:"<<endl;
	cout<<"D(X)=A(X)+B(X)=";  
    printflist(head_d);  
  
}  

多项式相加函数】

listnode *AddPoly(listnode *head_a,listnode *head_b)
{
	listnode *head_d,*pa,*pb,*pd,*newnode;
	pa=head_a;
	pb=head_b;
	if(pa->next==NULL && pb->next==NULL)   //当两项为空时或一项为空时 
        return NULL;  
	if(pa->next==NULL && pb->next!=NULL)
		return head_b;
	if(pa->next!=NULL && pb->next==NULL)
		return head_a;

	int max_qi;
	if( (pa->next->qi) > (pb->next->qi))
	    max_qi=pa->next->qi;
	else
		max_qi=pb->next->qi;       //找到最高次数

    head_d=(listnode *)malloc(sizeof(listnode));  
	if(NULL==head_d)  
	{   cout<<"构建链表D失败!"<<endl;  
		exit(-1);  
	}  
	
	
	head_d->pi=0.0;  
	head_d->qi=0;  
	head_d->next=NULL;  
	pd=head_d;  
	pa=pa->next;
	pb=pb->next;             //注:头结点不含项

	int qi=0;
	float pi=0.0;
	for(int i=max_qi;i>=0;i--)
	{ //*//
		if(NULL==(newnode=(listnode *)malloc(sizeof(listnode))))  
            {  
                printf("链表D节点创建失败");  
                exit(-1);  
            }  
		if(pa!=NULL && pb!=NULL)
		{
			if(pa->qi==i&&pb->qi==i)   //合并同类项       
				{ 
				  qi=i;
				  pi=pa->pi+pb->pi;
				  pa=pa->next;
				  pb=pb->next;
				
				}
			
			else if(pa->qi==i&&pb->qi<i)//某次数只有一项时
				{
					 qi=i;
					 pi=pa->pi;
					 pa=pa->next;
				}
			else if(pa->qi<i&&pb->qi==i)//某次数只有一项时
				{
					 qi=i;
					 pi=pb->pi;
					 pb=pb->next;
			    }
		}
       else if(pa!=NULL && pb==NULL)//pb已经算完,将pa复制到pd中
        {   if(pa->qi==i)
			{
				qi=i;
				pi=pa->pi;
				pa=pa->next;
			}
	    }
	  
	   else if(pa==NULL && pb!=NULL)//pa已经算完,将pb复制到pd中
        {       
			if(pb->qi==i)
			{
				qi=i;
				pi=pb->pi;
				pb=pb->next;
			}
	    }
	    else if(pa==NULL && pb==NULL) //两者算完,可提前结束循环
		   break;
		if(pi!=0.0)            //存在该项,则给新节点赋值,添加到pd上
		{
			newnode->pi=pi;  
			newnode->qi=qi; 
			newnode->next=NULL;
			pd->next=newnode;
			pd=newnode;
			pi=0.0;
		}
		} //*//
	return head_d;

	}

多项式相乘函数

listnode *MultiplyPoly(listnode *head_a,listnode *head_b)//链式相乘  
{     
    listnode *head_c,*pa=head_a,*pb=head_b,*pc,*newnode;  
    int qi_max;           //指数之和最大值  
    if(pa->next!=NULL && pb->next!=NULL)  
         qi_max=pa->next->qi+pb->next->qi; //获取最大指数和   
	else return CreateList(0);//*
    
    head_c=(listnode *)malloc(sizeof(listnode));  
    if(NULL==head_c)  
    {   cout<<"构建链表C失败!"<<endl;  
        exit(-1);  
    }  
    head_c->pi=0.0;  
    head_c->qi=0;  
    head_c->next=NULL;  
    pc=head_c;   
    InverseList(head_b);    //倒置b链表  
    float pi=0.0;  
    for(int k=qi_max;k>=0;k--)    
    {  
        pa=head_a->next; //恢复pa的指向  
        while(pa!=NULL && pa->qi>k) //查找pa的位置 不大于k的  
                pa=pa->next;  
        pb=head_b->next;//恢复Pb的指向  
        while(pa!=NULL && pb!=NULL && pa->qi+pb->qi<k)//然后在查找pb的位置 pa+pb的指数和不大于k  
                pb=pb->next;  
        
        while(pa!=NULL && pb!=NULL)//此循环,找到所有的同指数的和相加  
        {  
            if(k==pa->qi+pb->qi)  //找等于K的 
            {  
                pi+=pa->pi*pb->pi;  
                pa=pa->next;  
                pb=pb->next;  
            }  
            else  
            {  
                if(pa->qi+pb->qi<k) //小于k 增加pb  
                    pb=pb->next;  
                else 
                    pa=pa->next; //大于k 减小pa  
            }  
               
        }  
        if(pi!=0.0)   //有系数 就将此节点添加到c链表中  
        {  
            if(NULL==(newnode=(listnode *)malloc(sizeof(listnode))))  
            {  
                printf("链表C节点开辟失败");  
                exit(-1);  
            }  
           
            newnode->next=NULL; //插入节点数据  
            newnode->pi=pi;  
            newnode->qi=k;    
            pc->next=newnode;  
            pc=newnode;         //插入节点        
            pi=0.0;  
        }  
    }  
       
        InverseList(head_b);  
        return head_c;  
}  

四、运行结果

若有什么错误,恳请各位指出,谢谢~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值