多项式加减(数据结构乱杀+完整实验报告)

一.实验目的:

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

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

二.实验内容:

题目:一元多项式运算

问题描述:

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

基本要求:

    (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):两个多项式相减

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

#include

#include

using namespace std;

typedef struct node

{

    double mi;

    double xishu;

    struct node* next;



}LNode,*LinkList;

LinkList Creat_List()

{

    LinkList L = NULL;//有头节点

    LNode* s, * r = NULL;

    double x;

    double y;

    char c=NULL;



    cout << "输入系数和幂指数:";

    cout << endl;

    cin >> x>>y;

   

    s = (LNode*)malloc(sizeof(LNode));

   

    if (s == NULL) {

         cout << "调用失败";

    }

    else

         L = s;

    r = s;



    while (1)

    {

         s = (LNode*)malloc(sizeof(LNode));

         if (s == NULL) {

             cout << "调用失败";

         }

         else

         {

             s->xishu = x;

             s->mi = y;

             r->next = s;

         }

         r = s;

        

        

         cin >> x;

         cin >> y;

         if (x == 0 && y == 0)

         {

             break;

         }



    }

    r->next = NULL;

    return L;



}



bool Empty_List()

{

    return false;

}



LinkList add(LinkList L1, LinkList L2)

{

    LinkList L3=NULL;//无头节点

    LNode* s, * r = NULL;

    while (L1->next&&L2->next)

    {

        

         if (L1->next->mi == L2->next->mi)

         {

             L1 = L1->next;

             L2 = L2->next;

            

             s = (LNode*)malloc(sizeof(LNode));

             if (s == NULL)

                  cout << "调用失败";

             else

             {

                  s->xishu = L1->xishu + L2->xishu;

                  s->mi = L1->mi;

             }

             if (L3 == NULL)

                  L3 = s;

             else

                  r->next = s;

             r = s;

            

         }

         else if(L1->next->mi < L2->next->mi)

         {

             L1 = L1->next;

            

             s = (LNode*)malloc(sizeof(LNode));

             if (s == NULL)

                  cout << "调用失败";

             else

             {

                  s->xishu = L1->xishu;

                  s->mi = L1->mi;

             }

             if (L3 == NULL)

                  L3 = s;

             else

                  r->next = s;

             r = s;

        

         }

         else

         {

             L2 = L2->next;

             s = (LNode*)malloc(sizeof(LNode));

             if (s == NULL)

                  cout << "调用失败";

             else

             {

                  s->xishu = L2->xishu;

                  s->mi = L2->mi;

             }

             if (L3 == NULL)

                  L3 = s;

             else

                  r->next = s;

             r = s;

        

         }



        

    }

    while (L1->next)

    {

         L1 = L1->next;

         s = (LNode*)malloc(sizeof(LNode));

         if (s == NULL)

             cout << "调用失败";

         else

         {

             s->xishu = L1->xishu;

             s->mi = L1->mi;

         }

         if (L3 == NULL)

             L3 = s;

         else

             r->next = s;

         r = s;

   

   

    }

    while (L2->next)

    {

         L2 = L2->next;



         s = (LNode*)malloc(sizeof(LNode));

         if (s == NULL)

             cout << "调用失败";

         else

         {

             s->xishu = L2->xishu;

             s->mi = L2->mi;

         }

         if (L3 == NULL)

             L3 = s;

         else

             r->next = s;

         r = s;

        

    }



    r->next = NULL;

    return L3;

}

LinkList sub(LinkList L1, LinkList L2)

{

    LinkList L3 = NULL;

    LNode* s, * r = NULL;

    while (L1->next && L2->next)

    {



         if (L1->next->mi == L2->next->mi)

         {

             L1 = L1->next;

             L2 = L2->next;



             s = (LNode*)malloc(sizeof(LNode));

             if (s == NULL)

                  cout << "调用失败";

             else

             {

                  s->xishu = L1->xishu - L2->xishu;

                  s->mi = L1->mi;

             }

             if (L3 == NULL)

                  L3 = s;

             else

                  r->next = s;

             r = s;



         }

         else if (L1->next->mi < L2->next->mi)

         {

             L1 = L1->next;



             s = (LNode*)malloc(sizeof(LNode));

             if (s == NULL)

                  cout << "调用失败";

             else

             {

                  s->xishu = L1->xishu;

                  s->mi = L1->mi;

             }

             if (L3 == NULL)

                  L3 = s;

             else

                  r->next = s;

             r = s;



         }

         else

         {

             L2 = L2->next;

             s = (LNode*)malloc(sizeof(LNode));

             if (s == NULL)

                  cout << "调用失败";

             else

             {

                  s->xishu = -L2->xishu;

                  s->mi = L2->mi;

             }

             if (L3 == NULL)

                  L3 = s;

             else

                  r->next = s;

             r = s;



         }





    }

    while (L1->next)

    {

         L1 = L1->next;

         s = (LNode*)malloc(sizeof(LNode));

         if (s == NULL)

             cout << "调用失败";

         else

         {

             s->xishu = L1->xishu;

             s->mi = L1->mi;

         }

         if (L3 == NULL)

             L3 = s;

         else

             r->next = s;

         r = s;





    }

    while (L2->next)

    {

         L2 = L2->next;



         s = (LNode*)malloc(sizeof(LNode));

         if (s == NULL)

             cout << "调用失败";

         else

         {

             s->xishu =-(L2->xishu);

             s->mi = L2->mi;

         }

         if (L3 == NULL)

             L3 = s;

         else

             r->next = s;

         r = s;



    }



    r->next = NULL;

    return L3;

}

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

{

    LNode *p=NULL;

    while (L->next!=NULL)

    {

         L = L->next;

         if (L->xishu == 0)

         {

             p = L;

             continue;



         }

         else

         {

             cout << L->xishu << "X^" << L->mi << "  ";

             if (p != NULL)

             {

                  free(p);

             }

         }

    }

}

void output1(LinkList L)//无头结点输出

{

    while(L)

    {

         if (L->xishu == 0)

         {

             L = L->next;

             continue;             //continue直接跳出循环无法到下一个位置导致数据输出不全

         }

        

         else

         {

             cout << L->xishu << "X^" << L->mi << "  ";

         }

         L = L->next;



    }



}

int length1(LinkList L)//有头节点

{

    int n = 0;

    while (L->next)

    {

         n++;

         L = L->next;



    }

    return n;

}

int length2(LinkList L)

{

    int n = 0;

    while (L)

    {

         n++;

         L = L->next;

    }

    return n;

}

void func(LinkList L)//删除相邻结点mi相同的结点

{

    LNode* p;



    while (L->next!=NULL)

    {

         if (L->mi == L->next->mi)

         {

             p = L->next;

             L->xishu = L->xishu + L->next->xishu;

             L->next = L->next->next;

             free(p);//删掉相连第二个结点

             continue;//查看这个结点和第三个结点

         }

         L = L->next;

    }

}

void sort(LinkList L)

{

   

    int i, count , num;//count记录链表结点的个数,num进行内层循环,

    LNode* p, * q, * tail;//创建三个指针,进行冒泡排序

    count = length1(L);

    for (i = 0; i < count - 1; i++)//外层循环,跟数组冒泡排序一样

    {  

         num = count - i - 1;//内层循环次数

         q = L->next;//第一个结点

         p = q->next;//第二个结点

         tail = L;//第一个节点的前一个结点方便倒换

         while (num!=0)

         {

             if (q->mi > p->mi)

             {

                  q->next = p->next;

                  p->next = q;

                  tail->next = p;

                 

             }

            

                  tail = tail->next;//交换后p在前q在后这时用tail就可以重新调回

                  q = tail->next;

                  p = q->next;

                  num--;

         }

    }



}



int main()

{

    int n;

    LinkList L1 = NULL, L2 = NULL, L3 = NULL, L4 = NULL;

    cout << "请输入链表1(输入0 0结束输入)" << endl;

    L1 = Creat_List();

    sort(L1);//先排序

    cout << endl;

    cout << "链表1:";

    output(L1);//输出

    func(L1);//相邻系数合编

    cout << endl;

    cout << "请输入链表2(输入0 0结束输入)" << endl;

    L2 = Creat_List();

    sort(L2);//排序

    cout << endl;

    cout << "链表2:";

    output(L2);

    func(L2);//整合相邻系数相同项

    cout << endl<> n;

    if (n == 1)

    {

         L3 = add(L1, L2);

         cout << '\n';

         func(L3);

         cout << endl;

         cout << "两多项式相加结果是:";

         output1(L3);

         cout << endl << endl;

    }

    else if (n == 2)

    {

         L4 = sub(L1, L2);

         cout << '\n';

         func(L4);

         cout << endl;

         cout << "两多项式相减结果是:";

         output1(L4);

         cout << endl << endl;

    }

    else

         cout << "功能键错误";

    system("pause");

    return 0;

}

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

多项式加减(数据结构乱杀+完整实验报告)_第1张图片

多项式加减(数据结构乱杀+完整实验报告)_第2张图片

多项式加减(数据结构乱杀+完整实验报告)_第3张图片

 多项式加减(数据结构乱杀+完整实验报告)_第4张图片

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

问题一:在链表排序时用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后停止输入。

你可能感兴趣的:(数据结构,算法,链表)