單鏈表實現(xiàn)兩個多項式相加

兩個多項式合并

多項式 L1 與 L2
處理方法:將較短 L2 ,合并到長的 L1

通過逐項比較,依次添加

L1 連續(xù)三項指數(shù) : X ,Y , Z
L1 某項指數(shù) :N
L2 某項指數(shù) :M

  1. 當(dāng) M == N 相同,則兩項系數(shù)相加,然后 L1 與 L2 都跳到下一項

注意:存在系數(shù)為0 的情況,位于中間項的可以直接扼殺在搖籃,不占內(nèi)存空間,位于結(jié)尾的則需要單獨處理

  1. 當(dāng) X < M < Y ,則需要把 M項 插入到 X,Y 兩項 之間

  2. 開頭和結(jié)尾需要單獨處理,也存在三種可能,指數(shù)相同,指數(shù)位于兩項之間,指數(shù)在開頭結(jié)尾

多項式排序

方法:

  1. 從左到右剔除第一個順序有問題的項,并保存
  2. 將此項插入到合適的位置
  3. 依次執(zhí)行,直到?jīng)]有順序錯誤的項
#include "pch.h"
#include <iostream>
using namespace std;
/*
1 : 最后顯示時的符號問題 ,此方法:void FindPolyn(ListNode L);
2 : 系數(shù)為0,解決方法:void AddPolyn(ListNode &L1, ListNode L2);
3 : 兩個多項式相加時,在第一個多項式結(jié)尾出現(xiàn)系數(shù)為0,這個零無法直接在產(chǎn)生時去除,解決方法:void DelZeroPolyn(ListNode &L);
4 : 多項式排序
5 : 兩個多項式合并,釋放剩余的多項式的內(nèi)存空間
*/

#define LIST_SIZE sizeof(LNode)

typedef struct Polynomial
{
    float coef;
    int expn;
    struct Polynomial *next;
}LNode,*ListNode;

ListNode CreatePolyn();                             // 創(chuàng)建一個多項式
void FindPolyn      (ListNode L);                   // 查看多項式
int  LengthPolyn    (ListNode L);                   // 判斷多項式的長度
bool IsNULL         (ListNode L);                   // 判斷是否為空

bool AddOnePolyn    (ListNode &L1, ListNode &L2);   // 處理 多項式 與 只有一項的多項式
bool AddPolyn       (ListNode &L1, ListNode &L2);   // 合并多項式
void DelZeroPolyn   (ListNode &L);                  // 處理系數(shù)為零的情況

bool UnOrderPro     (ListNode& L, LNode * &e);      // 刪除按順序第一個錯誤位置的元素
bool SortPolyn(ListNode &L);                        // 插入刪除錯誤位置的元素
void ListLink       (ListNode &L, int length);      // 多項式排序

void UnRepetition(ListNode &L);                     // 多項式去重,前提條件,必須是有序多項式
void polynomial()
{
    ListNode L1 =  CreatePolyn();                   // 創(chuàng)建多項式
    cout << "_________________________"  << endl;
    ListNode L2 = CreatePolyn();                    // 創(chuàng)建多項式

    ListLink(L1, LengthPolyn(L1));                  // 多項式排序
    ListLink(L2, LengthPolyn(L2));                  // 多項式排序

    UnRepetition(L1);                               // 多項式去重
    UnRepetition(L2);                               // 多項式去重

    int n1 = LengthPolyn(L1);                       // 獲取多項式長度
    int n2 = LengthPolyn(L2);                       // 獲取多項式長度

    cout << "L1 = ";
    FindPolyn(L1);                                  // 查看多項式
    cout << "_________________________" << endl;
    cout << "L2 = ";
    FindPolyn(L2);                                  // 查看多項式
    cout << "_________________________" << endl;


    if (AddPolyn(L1, L2))                           // 合并多項式
    {
        DelZeroPolyn(L1);                           // 多項式去零
        cout
            << "L=";
        FindPolyn(L1);                              // 查看多項式
    }
    cout << "_________________________長度:" << endl;

    cout
        << n1 << "+" << n2 << "="
        << LengthPolyn(L1)                          // 獲取多項式長度
        << endl;
    cout << "_________________________" << endl;

    ListLink(L1, LengthPolyn(L1));                  // 多項式排序
    cout
        << "L=";
    FindPolyn(L1);                                  // 查看多項式

}

// 創(chuàng)建一個多項式
ListNode CreatePolyn()
{
    LNode * L = (ListNode)malloc(LIST_SIZE);
    if (!L) exit(1);
    L->next = NULL;

    LNode * p = (ListNode)malloc(LIST_SIZE),*q;
    if (!p) exit(1);
    int num = 1;
    cout << "第 " << num << " 項" << endl;
    cout << "輸入系數(shù):";
    cin >> p->coef;
    cout << "輸入指數(shù):";
    cin >> p->expn;
    q = L;
    while ( 1)
    {
        if (p->coef == 0)
        {
            q->next = NULL;
            break;
        }
        else
        {
            q->next = p;
            q = p;
            num++;
        }
        p = (ListNode)malloc(LIST_SIZE);
        if (!p) exit(1);
        cout << "第 " << num << " 項" << endl;
        cout << "輸入系數(shù):";
        cin >> p->coef;
        cout << "輸入指數(shù):";
        cin >> p->expn;
    }
    free(p);
    return L;
}

// 查看多項式
void FindPolyn(ListNode L)
{
    if (!L->next)
    {
        cout << 0 << endl;
        return;
    }
    ListNode p = L->next;
    while (p != NULL)
    {
        if (p->coef == 1)
        {
            // 系數(shù)為1,省略不寫
            if (p->expn == 0)
            {
                // 系數(shù)為1,同時指數(shù)為0,則需要顯示 1
                cout << p->coef;
            }
        }
        else
        {
            cout << p->coef;
        }

        if (p->expn != 0)
        {// 系數(shù)不為 0,指數(shù)為 0,則省略未知數(shù)部分
            if (p->coef == 1)
            {
                // 系數(shù)為一,省略乘號
                cout << "X^" << p->expn;
            }
            else
            {
                // 系數(shù)為一,顯示乘號
                cout << "·X^" << p->expn;
            }
        }
        if (p->next == NULL)
        {
            // 結(jié)尾,換行
            cout << endl;
        }
        else
        {
            // 判斷下一項的系數(shù),添加符號
            if(p->next->coef < 0)
                cout << " ";
            else
                cout << " + ";
        }

        p = p->next;
    }

}

// 判斷多項式的長度
int LengthPolyn(ListNode L)
{
    int num = 0;
    if (!L->next) return num;       // 判斷是否為空多項式
    ListNode p = L;
    while (p->next != NULL)
    {
        p = p->next;
        num++;
    }
    return num;
}
// 判斷是否為空
bool IsNULL(ListNode L)
{
    return L->next == NULL;
}

//處理 多項式 與 只有一項的多項式
bool AddOnePolyn(ListNode &L1, ListNode &L2)
{
    ListNode p1, p2 , q;
    if (LengthPolyn(L1) < LengthPolyn(L2))
    {
        // 第一個多項式長度 小于 第二個多項式
        p1 = L2, p2 = L1;
    }
    else
    {
        // 否則,默認
        p1 = L1, p2 = L2;
    }

    while (p1->next != NULL)
    {
        if (p2->expn == p1->expn)
        {
            // 當(dāng)指數(shù)相同,系數(shù)相加
            p1->coef = p1->coef + p2->coef;
            // 釋放內(nèi)存空間
            free(p2);
            return true;
        }
        else if (p2->expn > p1->expn && p2->expn < p1->next->expn)
        {
            // 位于第一個多項式某兩項之間
            // 新建空間 q ,存放 p2 的內(nèi)容
            q = (ListNode)malloc(LIST_SIZE);
            if (!q) exit(1);
            q->coef = p2->coef;
            q->expn = p2->expn;
            q->next = NULL;
            // 添加 q 到 p1 中
            q->next = p1->next;
            p1->next = q;
            // 釋放內(nèi)存空間
            free(p2);
            return true;
        }
        else if (p2->expn < L1->next->expn)
        {
            // 小于第一個多項式的第一項
            p2->next = p1;
            L1->next = p2;
            return true;
        }
        p1 = p1->next;
    }
        // 處理最后一項
    if (p1->next == NULL)
    {
        if (p2->expn == p1->expn)
        {
            // 當(dāng)指數(shù)相同,系數(shù)相加
            p1->coef = p1->coef + p2->coef;
            // 釋放內(nèi)存空間
            free(p2);
        }
        else
            p1->next = p2;
    }
    return true;
}

// 合并多項式
bool AddPolyn(ListNode &L1, ListNode &L2)
{
    if ((IsNULL(L1) && IsNULL(L2))
        || (!IsNULL(L1) && IsNULL(L2))
        )
    {
        // 兩個都為空
        // 第一個不為空,第二個為空
        return false;
    }
    else if (IsNULL(L1) && !IsNULL(L2))
    {
        // 第一個為空,第二個不為空
        L1 = L2;
        return true;
    }
    ListNode p1, p2;
    if (LengthPolyn(L1) < LengthPolyn(L2))
    {
        // 第一個多項式長度 小于 第二個多項式
        p1 = L2->next, p2 = L1->next;
    }
    else
    {
        // 否則,默認
        p1 = L1->next, p2 = L2->next;
    }


    ListNode q , p;
    // q 作用: 新建內(nèi)存,存放數(shù)據(jù)
    // p 作用: 釋放L2元素內(nèi)存空間

    //可以釋放L2頭節(jié)點
    L2->next = NULL;
    free(L2);

    // 若第二個多項式僅一項
    if (p2->next == NULL)
    {
        if (AddOnePolyn(p1, p2))
            return true;
        else
            return false;
    }


    while (1)
    {
        if (p1->next == NULL || p2->next == NULL)
        {// 當(dāng)一個多項式結(jié)束,則跳出循環(huán)
            break;
        }
        if (p1->expn == p2->expn)
        {
            // 當(dāng)指數(shù)相同,系數(shù)相加
            p1->coef = p1->coef + p2->coef;

            // 兩式均跳到下一項
            if (p1->coef == 0)
            {
                // 若系數(shù)為0,需要刪除本位元素,并釋放空間
                // 存在問題,最后一項系數(shù)為零無法去除,因此創(chuàng)建方法  void DelZeroPolyn(ListNode &L)  去除系數(shù)為零
                // 雖然 DelZeroPolyn 可以去除全部為零的項,但為了減少內(nèi)存占用,此處先去除中間的零
                if (p1->next != NULL)
                {
                    // 方法: 
                    // 把下一項傳過來,釋放下一項
                    // 先判斷下一項是否為空
                    q = p1->next;                   // 獲取下一項的地址
                    p1->coef = p1->next->coef;      // 修改 本項系數(shù) 為 下一項系數(shù)
                    p1->expn = p1->next->expn;      // 修改 本項指數(shù) 為 下一項指數(shù)
                    p1->next = p1->next->next;      // 指針 指向 下一項的下一項
                    free(q);                        // 釋放下一項的內(nèi)存空間
                }
            }
            else
            {
                p1 = p1->next;
            }

            p = p2;
            p2 = p2->next;
            // 釋放內(nèi)存空間
            free(p);
        }
        else if (p1->expn > p2->expn)
        {
            // 添加數(shù)據(jù)項
            // 若第一項指數(shù)大于第二項,因此第二項 遍歷直到遇到 第一項相同的指數(shù),中間的添加到 L1式中
            // 新建空間 q ,存放 p2 的內(nèi)容
            q = (ListNode)malloc(LIST_SIZE);
            if (!q) exit(1);
            q->coef = p2->coef;
            q->expn = p2->expn;
            q->next = NULL;
            // 添加 q 到 p1 中
            q->next = p1->next;
            p1->next = q;

            // 獲取p2當(dāng)前位置
            p = p2;
            // L2跳到下一項
            p2 = p2->next;
            p1 = p1->next;
            // 釋放內(nèi)存空間
            free(p);
        }
        else if (p1->expn < p2->expn)
        {
            // 若第一項指數(shù)小于第二項,遍歷到下一項
            p1 = p1->next;
        }

    }
    // 最后一項沒有進行檢測,因此需要在次檢測
    if ( (p1->next == NULL && p2->next == NULL) || (p2->next == NULL && p1->next != NULL))
    {
        if (AddOnePolyn(p1, p2))
            return true;
        else
            return false;
    }
    // 當(dāng)?shù)谝粋€多項式結(jié)束,第二個多項式仍存在,則把第二個多項式的內(nèi)容追加在第一個多項式后邊
    if (p1->next == NULL && p2->next != NULL)
    {
        p1->next = p2;
    }
}

// 處理系數(shù)為零的情況
void DelZeroPolyn(ListNode &L)
{
    // 判斷是否為空
    if (IsNULL(L))
    {
        return;
    }
    ListNode p = L->next , fr;

    // 處理第一項
    if (p->coef == 0)
    {
        L->next = p->next;
    }
    while (p->next->next != NULL)
    {
        if (p->next->coef == 0)
        {
            fr = p->next;
            p->next = fr->next;
            free(fr);
        }
        p = p->next;
    }
    // 處理最后一項
    if (p->next->coef == 0)
    {
        fr = p->next;
        p->next = NULL;
        free(fr);
    }
}

// 多項式排序
void ListLink(ListNode &L, int length)
{
    if (length < 0 || L->next == NULL) return;
    int i = 0;
    // 最多的可能項為 n-1
    while (i < length)
    {
        SortPolyn(L);
        i++;
    }
}

// 插入刪除錯誤位置的元素
bool SortPolyn(ListNode &L)
{
    if (IsNULL(L)) return false;
    ListNode e;
    if (!UnOrderPro(L, e))      // 獲取有問題的第一項
    {
        return false;
    }
    ListNode lo = L->next;
    // 判斷第一項,lo是第一項
    if (lo->expn >= e->expn)
    {
        e->next = lo;
        L->next = e;
        return true;
    }

    while (lo->next != NULL)
    {
        if (e->expn >= lo->expn && e->expn <= lo->next->expn)
        // 中間某項,指數(shù)在本項和后一項之間,便插入
        {
            e->next = lo->next;
            lo->next = e;
            break;
            return true;
        }
        lo = lo->next;
    }
    // 判斷最后一項
    if (lo->next == NULL && lo->expn <= e->expn)
    {
        lo->next = e;
        return true;
    }
    return false;
}

// 刪除書序有問題的指針,并返回該指針
bool UnOrderPro(ListNode &L,LNode * &e)
{
    if (IsNULL(L)) return false;            // 空的多項式
    ListNode p = L->next;

    // p 對應(yīng) 多項式的第一項
    if (p->next == NULL) return false;      // 若只有一項,直接返回

    if ( p->expn > p->next->expn)           // 判斷第一項是否合理
    {
        e = p;              // 獲取第一項
        L->next = p->next;  // 刪除第一項
        e->next = NULL;     // 修改第一項的next指針,防止影響原多項式
        return true;
    }
    
    // 除第一項和最后一項,中間第一個位置有問題的項
    while (p->next->next != NULL)
    {
        // 比較連續(xù)三項的指數(shù)
        if ( (  (p->expn < p->next->expn) && (p->next->expn > p->next->next->expn)  )   // 中間項 大于 前一項 且 大于 后一項
            ||  (p->expn > p->next->expn)           // 中間項 小于 前一項
            )
        {
            e = p->next;                // 獲取錯誤項
            p->next = p->next->next;    // 修改指針,刪除中間項
            e->next = NULL;             // 修改錯誤項的next指針,防止影響原多項式
            return true;
        }
        p = p->next;        // 遍歷到下一項
    }

    // 判斷最后一項是否正確
    if (p->next->next == NULL && (p->expn > p->next->expn) )
    {
        //比較最后兩項,若最后一項系數(shù)不正確,修改倒數(shù)第二次項的next指針
        e = p->next;
        e->next = NULL;             // 修改錯誤項的next指針,防止影響原多項式
        p->next = NULL;
        return true;
    }
    //當(dāng)順序正確,不刪除任何,進行初始化
    return false;
}

// 多項式去重,前提條件,必須是有序多項式
void UnRepetition(ListNode &L)
{
    if (IsNULL(L)) return;
    ListNode q = L->next;
    ListNode fr;
    while (q->next != NULL)
    {
        if (q->expn == q->next->expn)
        {
            // 連續(xù)兩項指數(shù)相等,系數(shù)相加,刪除后一項,并釋放內(nèi)存空間
            q->coef = q->coef + q->next->coef;
            fr = q->next;
            q->next = q->next->next;
            free(fr);
        }
        else
        {
            q = q->next;
        }
    }
}

簡便方法:直接將兩個多項式,合并,不排序,不去重,把最后的合并式直接去重,不需要寫上邊折磨復(fù)雜,把兩個多項式一項一項拼接,感覺有好多bug

void s()
{
    ListNode L1 = CreatePolyn();                    // 創(chuàng)建多項式
    cout << "_________________________" << endl;
    ListNode L2 = CreatePolyn();                    // 創(chuàng)建多項式
    ListNode p = L1;
    while (p->next != NULL)
    {
        p = p->next;
    }
    if(p->next == NULL)
        p->next = L2->next;
    cout << "_________________________" << endl;
    cout << "L" << " = ";
        FindPolyn(L1);
    cout << "_________________________" << endl;
    ListLink(L1, LengthPolyn(L1));
    cout << "L" << " = ";
    FindPolyn(L1);
    cout << "_________________________" << endl;
    UnRepetition(L1);
    cout << "L" << " = ";
    FindPolyn(L1);
}

現(xiàn)在處于學(xué)習(xí)階段,考慮問題時,可能不全面,程序可能存在Bug,沒有找到,歡迎指正,會及時處理并修改

個人感覺,還存在一些bug,寫的時候出現(xiàn)各種bug,處理起來都快吐了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,316評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,481評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,241評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,939評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,697評論 6 409
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,182評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,247評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,406評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,933評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,772評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,973評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,516評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,638評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,866評論 1 285
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,644評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,953評論 2 373