当前位置:   article > 正文

多项式加减(数据结构乱杀+完整实验报告)_用链表实现多项式相加实验可能出现的问题及解决方案

用链表实现多项式相加实验可能出现的问题及解决方案

一.实验目的:

理解线性表的基本逻辑结构,完成链表及循环链表的实现

通过实验进一步理解线性表的逻辑结构和存储结构,提高使用理论知识指导解决实际问题的能力,熟练掌握链表的实际应用。

二.实验内容:

题目:一元多项式运算

问题描述:

设计算法实现一元多项式的简单运算。

基本要求:

    (1) 输入并建立多项式;

    (2) 输出多项式;

    (3) 多项式加法

    (4) 多项式减法。

测试数据:

    (1)(2x+5x8-3.1x11)+(7-5x8+11x9)=(-3.1x11+11x9+2x+7)

(2)(6x-3-x+4.4x2-1.2x9)-(―6x―3+5.4x2-x2+7.8x15) =(―7.8x15―

1.2x9+12x―3―x)

    (3)(1+x+x2+x3+x4+x5)+(―x3―x4)=(1+x+x2+x5)

    (4)(x+x3)+(―x―x3)=0

    (5)(x+x100)+(x100+x200)=(x+2x100+x200)

    (6)(x+x2+x3)+0=x+x2+x3

三. 实验方案

(一)算法设计思路:

       总体思路:建立两个带头结点的单链表储存多项式,每个结点分别有一个系数、指数、指针。用户输入两个多项式的每一项系数及其对应指数,储存并将其按指数升序排序,并合并指数相同的项。若为加法,则直接将两多项式相加,若为减法,则将两多项式系数相减。输出结果多项式。

关键部分算法思路:

排序函数sort:(根据数据从小到大排列链表结点)

    每一个元素与后一个元素比较,若这个元素大于后一个元素,则交换这两个元素的结点位置,加一个tail指向第一个结点的前一个结点,q指向第一个结点,p指向第二个结点。每次交换完p与q后,tail指向下一个结点,并根据tail更新p与q。这样借用tail这个结点,就可以达到跟数组的冒泡排序一样的操作。

合并函数func:(合并相邻结点)

经过sort函数,若有幂指数相同的结点必然会成为相邻结点,把他们的系数相加,然后保存至第一个幂指数相同的结点上,然后free掉后一个结点,加个continue这个循环跳过L=L->next,接着比较这个结点与下一个结点是否幂指数相同(一次只能合并两个结点,不确定是否有多个结点幂相同)。遍历完毕即结束此函数。

(二)使用模块及变量的说明(例如结构体的定义、含义)

1、typedef struct node :定义多项式结点

2、LinkList Creat_List():创建带头节点的单链表储存多项式

3、int length1(LinkList L):有头节点长度

    int length2(LinkList L):无头节点长度

4、void output1(LinkList L):无头结点输出

    void output(LinkList L):有头节点输出

5、void func(LinkList L):删除合并相邻结点指数相同的结点

6、void sort(LinkList L):从小到大排序结点

7、LinkList add(LinkList L1, LinkList L2):两个多项式相加

8、LinkList sub(LinkList L1, LinkList L2):两个多项式相减

四. 实验步骤或程序(经调试后正确的源程序)

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. typedef struct node
  5. {
  6.     double mi;
  7.     double xishu;
  8.     struct node* next;
  9. }LNode,*LinkList;
  10. LinkList Creat_List()
  11. {
  12.     LinkList L = NULL;//有头节点
  13.     LNode* s, * r = NULL;
  14.     double x;
  15.     double y;
  16.     char c=NULL;
  17.     cout << "输入系数和幂指数:";
  18.     cout << endl;
  19.     cin >> x>>y;
  20.    
  21.     s = (LNode*)malloc(sizeof(LNode));
  22.    
  23.     if (s == NULL) {
  24.          cout << "调用失败";
  25.     }
  26.     else
  27.          L = s;
  28.     r = s;
  29.     while (1)
  30.     {
  31.          s = (LNode*)malloc(sizeof(LNode));
  32.          if (s == NULL) {
  33.              cout << "调用失败";
  34.          }
  35.          else
  36.          {
  37.              s->xishu = x;
  38.              s->mi = y;
  39.              r->next = s;
  40.          }
  41.          r = s;
  42.         
  43.         
  44.          cin >> x;
  45.          cin >> y;
  46.          if (x == 0 && y == 0)
  47.          {
  48.              break;
  49.          }
  50.     }
  51.     r->next = NULL;
  52.     return L;
  53. }
  54. bool Empty_List()
  55. {
  56.     return false;
  57. }
  58. LinkList add(LinkList L1, LinkList L2)
  59. {
  60.     LinkList L3=NULL;//无头节点
  61.     LNode* s, * r = NULL;
  62.     while (L1->next&&L2->next)
  63.     {
  64.         
  65.          if (L1->next->mi == L2->next->mi)
  66.          {
  67.              L1 = L1->next;
  68.              L2 = L2->next;
  69.             
  70.              s = (LNode*)malloc(sizeof(LNode));
  71.              if (s == NULL)
  72.                   cout << "调用失败";
  73.              else
  74.              {
  75.                   s->xishu = L1->xishu + L2->xishu;
  76.                   s->mi = L1->mi;
  77.              }
  78.              if (L3 == NULL)
  79.                   L3 = s;
  80.              else
  81.                   r->next = s;
  82.              r = s;
  83.             
  84.          }
  85.          else if(L1->next->mi < L2->next->mi)
  86.          {
  87.              L1 = L1->next;
  88.             
  89.              s = (LNode*)malloc(sizeof(LNode));
  90.              if (s == NULL)
  91.                   cout << "调用失败";
  92.              else
  93.              {
  94.                   s->xishu = L1->xishu;
  95.                   s->mi = L1->mi;
  96.              }
  97.              if (L3 == NULL)
  98.                   L3 = s;
  99.              else
  100.                   r->next = s;
  101.              r = s;
  102.         
  103.          }
  104.          else
  105.          {
  106.              L2 = L2->next;
  107.              s = (LNode*)malloc(sizeof(LNode));
  108.              if (s == NULL)
  109.                   cout << "调用失败";
  110.              else
  111.              {
  112.                   s->xishu = L2->xishu;
  113.                   s->mi = L2->mi;
  114.              }
  115.              if (L3 == NULL)
  116.                   L3 = s;
  117.              else
  118.                   r->next = s;
  119.              r = s;
  120.         
  121.          }
  122.         
  123.     }
  124.     while (L1->next)
  125.     {
  126.          L1 = L1->next;
  127.          s = (LNode*)malloc(sizeof(LNode));
  128.          if (s == NULL)
  129.              cout << "调用失败";
  130.          else
  131.          {
  132.              s->xishu = L1->xishu;
  133.              s->mi = L1->mi;
  134.          }
  135.          if (L3 == NULL)
  136.              L3 = s;
  137.          else
  138.              r->next = s;
  139.          r = s;
  140.    
  141.    
  142.     }
  143.     while (L2->next)
  144.     {
  145.          L2 = L2->next;
  146.          s = (LNode*)malloc(sizeof(LNode));
  147.          if (s == NULL)
  148.              cout << "调用失败";
  149.          else
  150.          {
  151.              s->xishu = L2->xishu;
  152.              s->mi = L2->mi;
  153.          }
  154.          if (L3 == NULL)
  155.              L3 = s;
  156.          else
  157.              r->next = s;
  158.          r = s;
  159.         
  160.     }
  161.     r->next = NULL;
  162.     return L3;
  163. }
  164. LinkList sub(LinkList L1, LinkList L2)
  165. {
  166.     LinkList L3 = NULL;
  167.     LNode* s, * r = NULL;
  168.     while (L1->next && L2->next)
  169.     {
  170.          if (L1->next->mi == L2->next->mi)
  171.          {
  172.              L1 = L1->next;
  173.              L2 = L2->next;
  174.              s = (LNode*)malloc(sizeof(LNode));
  175.              if (s == NULL)
  176.                   cout << "调用失败";
  177.              else
  178.              {
  179.                   s->xishu = L1->xishu - L2->xishu;
  180.                   s->mi = L1->mi;
  181.              }
  182.              if (L3 == NULL)
  183.                   L3 = s;
  184.              else
  185.                   r->next = s;
  186.              r = s;
  187.          }
  188.          else if (L1->next->mi < L2->next->mi)
  189.          {
  190.              L1 = L1->next;
  191.              s = (LNode*)malloc(sizeof(LNode));
  192.              if (s == NULL)
  193.                   cout << "调用失败";
  194.              else
  195.              {
  196.                   s->xishu = L1->xishu;
  197.                   s->mi = L1->mi;
  198.              }
  199.              if (L3 == NULL)
  200.                   L3 = s;
  201.              else
  202.                   r->next = s;
  203.              r = s;
  204.          }
  205.          else
  206.          {
  207.              L2 = L2->next;
  208.              s = (LNode*)malloc(sizeof(LNode));
  209.              if (s == NULL)
  210.                   cout << "调用失败";
  211.              else
  212.              {
  213.                   s->xishu = -L2->xishu;
  214.                   s->mi = L2->mi;
  215.              }
  216.              if (L3 == NULL)
  217.                   L3 = s;
  218.              else
  219.                   r->next = s;
  220.              r = s;
  221.          }
  222.     }
  223.     while (L1->next)
  224.     {
  225.          L1 = L1->next;
  226.          s = (LNode*)malloc(sizeof(LNode));
  227.          if (s == NULL)
  228.              cout << "调用失败";
  229.          else
  230.          {
  231.              s->xishu = L1->xishu;
  232.              s->mi = L1->mi;
  233.          }
  234.          if (L3 == NULL)
  235.              L3 = s;
  236.          else
  237.              r->next = s;
  238.          r = s;
  239.     }
  240.     while (L2->next)
  241.     {
  242.          L2 = L2->next;
  243.          s = (LNode*)malloc(sizeof(LNode));
  244.          if (s == NULL)
  245.              cout << "调用失败";
  246.          else
  247.          {
  248.              s->xishu =-(L2->xishu);
  249.              s->mi = L2->mi;
  250.          }
  251.          if (L3 == NULL)
  252.              L3 = s;
  253.          else
  254.              r->next = s;
  255.          r = s;
  256.     }
  257.     r->next = NULL;
  258.     return L3;
  259. }
  260. void output(LinkList L)//有头节点输出
  261. {
  262.     LNode *p=NULL;
  263.     while (L->next!=NULL)
  264.     {
  265.          L = L->next;
  266.          if (L->xishu == 0)
  267.          {
  268.              p = L;
  269.              continue;
  270.          }
  271.          else
  272.          {
  273.              cout << L->xishu << "X^" << L->mi << "  ";
  274.              if (p != NULL)
  275.              {
  276.                   free(p);
  277.              }
  278.          }
  279.     }
  280. }
  281. void output1(LinkList L)//无头结点输出
  282. {
  283.     while(L)
  284.     {
  285.          if (L->xishu == 0)
  286.          {
  287.              L = L->next;
  288.              continue;             //continue直接跳出循环无法到下一个位置导致数据输出不全
  289.          }
  290.         
  291.          else
  292.          {
  293.              cout << L->xishu << "X^" << L->mi << "  ";
  294.          }
  295.          L = L->next;
  296.     }
  297. }
  298. int length1(LinkList L)//有头节点
  299. {
  300.     int n = 0;
  301.     while (L->next)
  302.     {
  303.          n++;
  304.          L = L->next;
  305.     }
  306.     return n;
  307. }
  308. int length2(LinkList L)
  309. {
  310.     int n = 0;
  311.     while (L)
  312.     {
  313.          n++;
  314.          L = L->next;
  315.     }
  316.     return n;
  317. }
  318. void func(LinkList L)//删除相邻结点mi相同的结点
  319. {
  320.     LNode* p;
  321.     while (L->next!=NULL)
  322.     {
  323.          if (L->mi == L->next->mi)
  324.          {
  325.              p = L->next;
  326.              L->xishu = L->xishu + L->next->xishu;
  327.              L->next = L->next->next;
  328.              free(p);//删掉相连第二个结点
  329.              continue;//查看这个结点和第三个结点
  330.          }
  331.          L = L->next;
  332.     }
  333. }
  334. void sort(LinkList L)
  335. {
  336.    
  337.     int i, count , num;//count记录链表结点的个数,num进行内层循环,
  338.     LNode* p, * q, * tail;//创建三个指针,进行冒泡排序
  339.     count = length1(L);
  340.     for (i = 0; i < count - 1; i++)//外层循环,跟数组冒泡排序一样
  341.     {  
  342.          num = count - i - 1;//内层循环次数
  343.          q = L->next;//第一个结点
  344.          p = q->next;//第二个结点
  345.          tail = L;//第一个节点的前一个结点方便倒换
  346.          while (num!=0)
  347.          {
  348.              if (q->mi > p->mi)
  349.              {
  350.                   q->next = p->next;
  351.                   p->next = q;
  352.                   tail->next = p;
  353.                  
  354.              }
  355.             
  356.                   tail = tail->next;//交换后p在前q在后这时用tail就可以重新调回
  357.                   q = tail->next;
  358.                   p = q->next;
  359.                   num--;
  360.          }
  361.     }
  362. }
  363. int main()
  364. {
  365.     int n;
  366.     LinkList L1 = NULL, L2 = NULL, L3 = NULL, L4 = NULL;
  367.     cout << "请输入链表1(输入0 0结束输入)" << endl;
  368.     L1 = Creat_List();
  369.     sort(L1);//先排序
  370.     cout << endl;
  371.     cout << "链表1:";
  372.     output(L1);//输出
  373.     func(L1);//相邻系数合编
  374.     cout << endl;
  375.     cout << "请输入链表2(输入0 0结束输入)" << endl;
  376.     L2 = Creat_List();
  377.     sort(L2);//排序
  378.     cout << endl;
  379.     cout << "链表2:";
  380.     output(L2);
  381.     func(L2);//整合相邻系数相同项
  382.     cout << endl<<endl;
  383.     cout << "***********"<<endl;
  384.     cout << "1-多项式加法"<<endl;
  385.     cout << "2-多项式减法"<< endl;
  386.     cout << "请选择:";
  387.     cin >> n;
  388.     if (n == 1)
  389.     {
  390.          L3 = add(L1, L2);
  391.          cout << '\n';
  392.          func(L3);
  393.          cout << endl;
  394.          cout << "两多项式相加结果是:";
  395.          output1(L3);
  396.          cout << endl << endl;
  397.     }
  398.     else if (n == 2)
  399.     {
  400.          L4 = sub(L1, L2);
  401.          cout << '\n';
  402.          func(L4);
  403.          cout << endl;
  404.          cout << "两多项式相减结果是:";
  405.          output1(L4);
  406.          cout << endl << endl;
  407.     }
  408.     else
  409.          cout << "功能键错误";
  410.     system("pause");
  411.     return 0;
  412. }

五.程序运行结果(程序运行结果的一些截图)

 

六.实验总结(调试过程中遇到哪些问题,怎么解决的)

问题一:在链表排序时用while(p!=null)来控制循环遍历但交换后结点发生混乱p和q在不断交替。

       通过查阅资料发现了一种很好的方法,用tail来控制进度tail在第一位(指向头节点),q指向第一个结点,p指向第二个结点,p,q交换并且tail=tail.next,再用tail更新q和p重新指向tail后的第一个结点与第二个结点。

问题二:合并结点时出现如果相邻两个相同指数可以合并,但三个及以上指数相同的的结点就合并出错了,有漏掉的。

       仔细调试后发现是每次执行玩之后L=L.next就跳过了合并成功的这个结点与下一个结点的比较,所以我在合并完之后加了一个continue,让他合并后不在执行这个L=L.next,完美解决问题。

问题三:多项式相加时怎样才能挑选正确的结点连接在C后面

       刚开始想两条链表一起向后遍历,但是由于还没有排序,无法判断后面与前面的关系,想着人工排序但又显得呆板,不符合时间,就加了sort排序后问题解决。

问题四:在输入数据的时候由于我设置是浮点型数据我用的while循环判定想着输入一个特殊字符后停止输入,但是一输入非浮点型数据就造成非法输入卡住了

       我想这设置输入的次数,可是这个对程序员和用户就太繁琐了,所以为此我只能设定极特殊情况,系数和指数都是0后停止输入。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/169304?site
推荐阅读
相关标签
  

闽ICP备14008679号