多項式的相加


多項式的相加

一、案例分析

  假如說我們現在有下面兩個多項式:

  ①A(x)=3x2+4x5+5x3-x1

  ②B(x)=4x3+7x2+3x1

  這兩個多項式在計算機中用鏈表的來存儲

根據多項式相加的運算規則:對兩個多項式中所有指數相同的項,對應系數想加,若其和不為零,則作為“和多項式”中的一項插入到“和多項式”鏈表中去;對於兩個多項式中指數不相同的項,則將指數較小的項插入到“和多項式”鏈表中去。“多項式”鏈表中的節點無需生成,而應該從兩個多項式的鏈表中摘取。

二、案例實現

(一)代碼分析

1.預處理部分

#include <iostream>
using namespace std;

#define OK 1
#define ERROR 0
#define ElemType int

int flag = 1;    //定義一個標志變量,來區分輸出的F(x)

2.結構體

鏈表的每個節點都有三個,系數(data)、指數(index)和一個指針域(next)。

typedef struct Polyn     //定義一個結構體,包括三個成員變量
{
    ElemType data;        //系數
    ElemType index;       //指數
    struct Polyn *next;  //結構體指針
}Polyn,*LinkList;

3.輸出鏈表

輸出鏈表是為了便於觀察我們創建的鏈表,以及后面輸出同類型和的鏈表。

  具體實現:①首先聲明一個指針指向首元結點

       ②while,在p不為空的情況下按照多項式的形式輸出節點,並按照系數的正負,分情況輸出

void Printf_Polyn(LinkList L)   //輸出鏈表
{
    Polyn *p = L->next;         //定義一個指向首節點的指針
    cout<<"F(x"<<flag<<")=";   //使輸出美觀
    while(p)                   //while循環遍歷鏈表,逐個輸出
    {
        if(p->data > 0)       //判斷系數是否為正,若為正數則加上"+",負數的話,只需正常輸出即可
        {
            cout<<"+"<<p->data<<"X^"<<p->index;
        }
        else cout<<p->data<<"X^"<<p->index;
        p=p->next;            //指針下移
    }
    cout<<endl;
}

4.對鏈表進行排序

使用選擇排序,對鏈表每個元素進行排序

  具體實現:①定義一個中間變量,便於后面的數據交換。

       ②排序時,首先取到第一個結點的指數,逐個與后面結點的指數比較,第二次用第二個結點的指數與后面結點指數比較,依次類推。

       ③如果前面的指數比后面的指數大,就交換,這樣比下去即可實現排序

 

void Sort_Polyn(LinkList &L)     //使用選擇法對鏈表進行排序
{   int temp_data,temp_index;    //定義一個中間變量,便於后面的數據交換
    Polyn *k,*r,*p = L->next;
    for(;p;p=p->next)            //從鏈表第一個節點開始,逐個與后面的節點比較
    {
        k = p;                   //k指向第一個節點的,比較完一輪之后,將會指向第二個節點,依次往后推
        for(r=p->next;r;r=r->next)   //從第二節點值開始與k所指節點值進行比較,比較完一輪之后,就是第三節點與k比較,依次類推
        {
            if(k->index > r->index)  //如果k指向的節點的值大,就交換系數和指數
            {
                temp_index = r->index;
                temp_data = r->data;
                r->data = k->data;
                r->index = k->index;
                k->data = temp_data;
                k->index = temp_index;
            }
        }
    }
    Printf_Polyn(L);               //輸出鏈表
    flag++;
}

5.創建鏈表

采用尾插法創建鏈表。

具體實現參考我上篇博客:單鏈表的基本操作和實現https://www.cnblogs.com/953-zjf/p/LinkList.html

void Creat_Polyn(LinkList &L)      //尾插法創建鏈表
{
    int n;                         //項數n
    if(flag % 2)                   //為了使程序更直觀而設立的標志變量
    {
        cout<<"現在輸入第一個多項式"<<endl;
    }
    else cout<<"現在輸入第二個多項式"<<endl;
    cout<<"請輸入你要創建的項數:";
    cin>>n;                      //輸入項數
    Polyn *p,*r;                 //一個新建節點的指針和一個尾指針
    L = new Polyn;               //初始化頭節點
    L->next = NULL;
    r = L;
    cout<<"請輸入系數和指數(系數和指數之間用空格隔開):";
    for(int j = 1;j <= n;j++)    //循環n次,每次新建一個節點
    {
        p = new Polyn;
        cin>>p->data>>p->index;  //輸入新節點的系數和指數
        p->next = r->next;       //接尾
        r->next = p;             //接頭
        r = p;                   //尾指針后移
    }
}

6.鏈表的合並

基本的思想就是分別先定義兩個指針分別指向兩個鏈表,至於兩個鏈表的和,可以新建一個鏈表來存放,也可以直接用兩個鏈表的其中一個來存儲。我這里用的La存儲,那么也需要一個指針來指向它,就是r。做好這些我們就可以來進行比較了,La中每個結點與Lb的每個結點進行比較,會出現三種情況,第一種:La的大於Lb,就將La的結點接到r上,然后指La的指針下移。第二種,La的小於Lb,就將Lb的結點接到r上,然后Lb的指針下移。第三種:La等於Lb,那就將兩個結點之和相加,這時候先判斷兩個之和是否為0,不為0,就將兩者之和賦給La的結點,並將該結點接上,然后刪除Lb的節點。如果兩者之和為0.則將兩個節點都刪除。

void Addit_Polyn(LinkList L1,LinkList L2)  //將兩個鏈表相加的函數
{
    Polyn *p1,*p2,*r,*s;           //定義四個結構體指針
    p1 = L1->next;                 //p1指向第一個鏈表
    p2 = L2->next;                 //p2指向第二個鏈表
    r = L1;                        //r指向p1,p1指得鏈條接下來也將成為和的鏈表的
    while(p1 != NULL&&p2 != NULL) //當p1、p2不指向空時,循環繼續
    {
        if(p1->index < p2->index) //判斷——如果p1的指數小於p2的指數,就將p1插到L1所指的鏈表
        {
            r->next = p1;
            r = p1;
            p1 = p1->next;       //指針p1下移
        }
        else if(p1->index > p2->index)//判斷——如果p1的指數大於p2的指數,就將p2插到L1所指的鏈表
        {
            r->next = p2;
            r = p2;
            p2  = p2->next;     //指針p2下移
        }
        else if(p1->index == p2->index)       //判斷——如果p1的指數等於p2的指數
        {
            if(p1->data + p2->data)//就先判斷系數之和是否為0,如果不是0
            {
                p1->data = p1->data+p2->data;   //將p1、p2系數之和賦值給p1
                r->next = p1;                   //p1接入L1
                r = p1;                        //r后移
                p1 = p1->next;                 //p1后移
                s = p2;                        //記錄p2,記錄之后,后面可以釋放該節點
                p2 = p2->next;                 //記錄之后,p2下移
                delete s;                      //釋放上一節點
            }
            else                               //如果p1、p2系數之和為0
            {
                s = p1;             //先分別用s記錄p1、p2,p1、p2下移,再分別釋放s,即刪除了前面p1和p2相等的兩個節點
                p1 = p1->next;
                delete s;
                s = p2;
                p2 = p2->next;
                delete s;
            }
        }
        r->next = NULL;      //結束循環時,先讓鏈表和的鏈表的尾部指向空
    }
    if(p1 != NULL)           //判斷剩余的p1是否為空
    {
        r->next = p1;        //如果剩余的p1不是空,就接到L1的后邊
    }
    else if(p2!=NULL)       //判斷剩余的p2是否為空
    {
        r->next = p2;       //如果剩余的p1不是空,就接到L1的后邊
    }
    Printf_Polyn(L1);       //輸出鏈表
}

7.主程序

首先新建兩個鏈表頭指針,然后只需分別調用上面的函數即可

int main()
{
    LinkList La,Lb;        //定義兩個鏈表指針
    Creat_Polyn(La);       //創建鏈表La
    Sort_Polyn(La);         //鏈表La排序
    Merge_Polyn(La);
    Creat_Polyn(Lb);       //創建鏈表Lb
    Sort_Polyn(Lb);
    Merge_Polyn(Lb);        //鏈表Lb排序
    cout<<"合並之后的多項式為:";
    Addit_Polyn(La,Lb);    //將兩個鏈表相加
    return 0;
}

8.完整代碼

#include <iostream>
using namespace std;

#define OK 1
#define ERROR 0
#define ElemType int

int flag = 1;             //定義一個標志變量,來區分輸出的F(x)
typedef struct Polyn     //定義一個結構體,包括三個成員變量
{
    ElemType data;        //系數
    ElemType index;       //指數
    struct Polyn *next;  //結構體指針
}Polyn,*LinkList;


void Printf_Polyn(LinkList L)   //輸出鏈表
{
    Polyn *p = L->next;         //定義一個指向首節點的指針
    cout<<"F(x"<<flag<<")=";   //使輸出美觀
    while(p)                   //while循環遍歷鏈表,逐個輸出
    {
        if(p->data > 0)       //判斷系數是否為正,若為正數則加上"+",負數的話,只需正常輸出即可
        {
            cout<<"+"<<p->data<<"X^"<<p->index;
        }
        else cout<<p->data<<"X^"<<p->index;
        p=p->next;            //指針下移
    }
    cout<<endl;
}

void Sort_Polyn(LinkList &L)     //使用選擇法對鏈表進行排序
{   int temp_data,temp_index;    //定義一個中間變量,便於后面的數據交換
    Polyn *k,*r,*p = L->next;
    for(;p;p=p->next)            //從鏈表第一個節點開始,逐個與后面的節點比較
    {
        k = p;                   //k指向第一個節點的,比較完一輪之后,將會指向第二個節點,依次往后推
        for(r=p->next;r;r=r->next)   //從第二節點值開始與k所指節點值進行比較,比較完一輪之后,就是第三節點與k比較,依次類推
        {
            if(k->index > r->index)  //如果k指向的節點的值大,就交換系數和指數
            {
                temp_index = r->index;
                temp_data = r->data;
                r->data = k->data;
                r->index = k->index;
                k->data = temp_data;
                k->index = temp_index;
            }
        }
    }
    Printf_Polyn(L);               //輸出鏈表
    flag++;
}
void Creat_Polyn(LinkList &L)      //尾插法創建鏈表
{
    int n;                         //項數n
    if(flag % 2)                   //為了使程序更直觀而設立的標志變量
    {
        cout<<"現在輸入第一個多項式"<<endl;
    }
    else cout<<"現在輸入第二個多項式"<<endl;
    cout<<"請輸入你要創建的項數:";
    cin>>n;                      //輸入項數
    Polyn *p,*r;                 //一個新建節點的指針和一個尾指針
    L = new Polyn;               //初始化頭節點
    L->next = NULL;
    r = L;
    cout<<"請輸入系數和指數(系數和指數之間用空格隔開):";
    for(int j = 1;j <= n;j++)    //循環n次,每次新建一個節點
    {
        p = new Polyn;
        cin>>p->data>>p->index;  //輸入新節點的系數和指數
        p->next = r->next;       //接尾
        r->next = p;             //接頭
        r = p;                   //尾指針后移
    }
}

void Addit_Polyn(LinkList L1,LinkList L2)  //將兩個鏈表相加的函數
{
    Polyn *p1,*p2,*r,*s;           //定義四個結構體指針
    p1 = L1->next;                 //p1指向第一個鏈表
    p2 = L2->next;                 //p2指向第二個鏈表
    r = L1;                        //r指向p1,p1指得鏈條接下來也將成為和的鏈表的
    while(p1 != NULL&&p2 != NULL) //當p1、p2不指向空時,循環繼續
    {
        if(p1->index < p2->index) //判斷——如果p1的指數小於p2的指數,就將p1插到L1所指的鏈表
        {
            r->next = p1;
            r = p1;
            p1 = p1->next;       //指針p1下移
        }
        else if(p1->index > p2->index)//判斷——如果p1的指數大於p2的指數,就將p2插到L1所指的鏈表
        {
            r->next = p2;
            r = p2;
            p2  = p2->next;     //指針p2下移
        }
        else if(p1->index == p2->index)       //判斷——如果p1的指數等於p2的指數
        {
            if(p1->data + p2->data)//就先判斷系數之和是否為0,如果不是0
            {
                p1->data = p1->data+p2->data;   //將p1、p2系數之和賦值給p1
                r->next = p1;                   //p1接入L1
                r = p1;                        //r后移
                p1 = p1->next;                 //p1后移
                s = p2;                        //記錄p2,記錄之后,后面可以釋放該節點
                p2 = p2->next;                 //記錄之后,p2下移
                delete s;                      //釋放上一節點
            }
            else                               //如果p1、p2系數之和為0
            {
                s = p1;             //先分別用s記錄p1、p2,p1、p2下移,再分別釋放s,即刪除了前面p1和p2相等的兩個節點
                p1 = p1->next;
                delete s;
                s = p2;
                p2 = p2->next;
                delete s;
            }
        }
        r->next = NULL;      //結束循環時,先讓鏈表和的鏈表的尾部指向空
    }
    if(p1 != NULL)           //判斷剩余的p1是否為空
    {
        r->next = p1;        //如果剩余的p1不是空,就接到L1的后邊
    }
    else if(p2!=NULL)       //判斷剩余的p2是否為空
    {
        r->next = p2;       //如果剩余的p1不是空,就接到L1的后邊
    }
    Printf_Polyn(L1);       //輸出鏈表
}
int main()
{
    LinkList La,Lb;        //定義兩個鏈表指針
    Creat_Polyn(La);       //創建鏈表La
    Sort_Polyn(La);         //鏈表La排序
    Merge_Polyn(La);
    Creat_Polyn(Lb);       //創建鏈表Lb
    Sort_Polyn(Lb);
    Merge_Polyn(Lb);        //鏈表Lb排序
    cout<<"合並之后的多項式為:";
    Addit_Polyn(La,Lb);    //將兩個鏈表相加
    return 0;
}

三、運行結果

如有什么不對的地方,歡迎大家指正!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM