单向链表的运用---一元多项式的加减详解

单向链表的运用---一元多项式的加减


线性表是最简单的最常用的数据结构,而多项式的操作则是表处理的典型用例。所以关于用线性表处理一元多项式的加减就是一个非常典型的例题了。


一元多项式分析:
一元多项式通式我们可以写成: y=ax+bx2+cx3+dx4+…+zxn 的形式。所以我们可以创立一个单项链表来储存这个多项式。在每一个节点中分别储存它的指数和系数。如图:

在这里插入图片描述
多项式相加分析
对有序单链表pa,pb进行扫描,对他们每个节点中的指数进行比较,有一下三种情况:
1、qa->expn < qb->expn
则qa中的节点后移,qa->next。qb不动。
在这里插入图片描述
2、qa->expn = qb->expn
先求两节点的和,若和不为零,则将qb的节点上的系数值加到qa上去,释放qb节点,qa、qb同时后移。
在这里插入图片描述
若和为零,从pa中删除qa所指向的节点并释放,同时释放qb的节点,qa和qb同时后移。

在这里插入图片描述

3、qa->expn > qb->expn
从pb中删除该节点,并将其插入到pa链表中qa所指的节点之前,qb后移,qa不动。
在这里插入图片描述
第一眼看过去可能有些迷惑,通俗点讲就是把pb链表加到pa链表上去,当pa中x的指数小于pb中的时就拿pa链表的下一个值跟pa的这个进行比较。当pa中的指数等于pb中的时,就让他们的系数相加,结果为零,就把这个节点删除,不为零就把系数相加,储存到pa中。当pa中的指数大于pb中的时,就把pb这个节点的值插到pa这个节点前,然后再比较下一项。
这样,多项式的相加就完成了。下面时我测试同过了的c++的代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
typedef struct term{//多项式项的结构定义
  float coef;
  int expn;
  struct term *next;
}term,*Linklist;

void CreateList_L(Linklist &L,int m){//建立一个带头节点的含有m项的多项式链表L
  int i;
  term *p;
  L = (term*)malloc(sizeof(term));
  L->next = NULL;
  printf("请从高到低输入系数,指数\n");
  for(i=m;i>0;--i){
    p = (term*)malloc(sizeof(term));
    printf("系数= ");scanf("%f",&p->coef);
    printf("指数= ");scanf("%d",&p->expn);
    p->next = L->next;
    L->next = p;
  }
  if(m){
    printf("链表创建成功!!\n");
  }else{
  printf("创建失败了!");}
}

char cmp(int qa_expn,int qb_expn){//比较两个多项式当前对应项的次数
  if(qa_expn == qb_expn)
  {
    return '=';
  }
  else if(qa_expn > qb_expn)
  {
    return '>';
  }

  else
  {
    return '<';
  }

}

void AddPolyn(Linklist &pa,Linklist &pb){
  term *qa,*qb,*pre,*u;
  float sum;
  qa = pa->next;
  qb = pb->next;
  pre = pa;
  while(qa&&qb)//当qa,qb链表都未结束时
    switch(cmp(qa->expn,qb->expn)){//用上面编写的cmp函数比较qa,qb的指数大小
  case '<':
    pre = qa;
    qa = qa->next;
    break;
  case '=':
    sum = qa->coef + qb->coef;
     if(sum!=0.0){
        qa->coef = sum;//sum加到qa当前的项里
        pre = qa;//pre记住当前qa
    }else{
      pre->next=qa->next;//pre的下一项指向qa的下一项
      free(qa);//释放此时的qa的项
    }
    qa = pre->next;//qa在pre所指的基础上向后移动
    u = qb;//u记录下当前的qb
    qb = qb->next;//qb指向pb的下一个
    free(u);//释放u,即当前pb的这一项
    break;
  case '>':
    u = qb->next;//u记录下当前qb所指的下一项
    qb->next = qa;//qb的下一项指向qa
    pre->next = qb;//pre的下一项指向qb
    pre = qb;//pre与qb相等
    qb = u;//qb与u相等
    break;
    }
    if(!qa){
        pre->next = qb;
    }
    free(pb);
    return;

}

int main()
{
    term *pa,*pb,*p;
    int InitLNodeNum_pa,InitLNodeNum_pb;
    printf("pa你想创建多少个节点?\n");
    scanf("%d",&InitLNodeNum_pa);
    CreateList_L(pa,InitLNodeNum_pa);//创建pa链表
    printf("pb你想创建多少个节点?\n");
    scanf("%d",&InitLNodeNum_pb);
    CreateList_L(pb,InitLNodeNum_pb);//创建pb链表
    AddPolyn(pa,pb);//相加
    p = pa;
    while(p->next){//输出结果
        p= p->next;
        printf("pc.corf=%f ,pc.expn=%d",p->coef,p->expn);
        printf("\n");
    }

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值