DHU26 有序鏈表ADT模板簡單應(yīng)用算法設(shè)計:一元多項式的加/減法運算

問題描述 :
目的:使用C++模板設(shè)計單鏈表的抽象數(shù)據(jù)類型(ADT)国葬。并在此基礎(chǔ)上贤徒,稍加改動,針對一元多項式建立相應(yīng)的稀疏多項式ADT汇四,使用單鏈表ADT的基本操作接奈,設(shè)計并實現(xiàn)稀疏一元多項式的加法計算的算法設(shè)計。

內(nèi)容:(1)請參照單鏈表的ADT模板通孽,設(shè)計稀疏一元多項式的抽象數(shù)據(jù)類型序宦。(由于該環(huán)境目前僅支持單文件的編譯,故將所有內(nèi)容都集中在一個源文件內(nèi)背苦。在實際的設(shè)計中互捌,推薦將抽象類及對應(yīng)的派生類分別放在單獨的頭文件中。參考網(wǎng)盤中的單鏈表ADT原型文件行剂,自行設(shè)計稀疏一元多項式的ADT秕噪。)

(2)ADT的簡單應(yīng)用:使用該ADT設(shè)計并實現(xiàn)稀疏一元多項式的加法計算的算法設(shè)計。

應(yīng)用1:假設(shè)2個稀疏一元多項式分別由帶頭結(jié)點的有序單鏈表A和B存儲(指數(shù)項遞增有序)『裨祝現(xiàn)要求設(shè)計一個算法腌巾,實現(xiàn)稀疏一元多項式的加減法計算。要求使用A和B的原存儲空間铲觉,且計算后B不再單獨存在澈蝙。輸入中的單鏈表的長度不得在計算算法中利用,僅作為建表使用撵幽。

注意:加/減法計算后灯荧,如某一項的結(jié)果系數(shù)為0,則該項要從多項式鏈表中刪除盐杂。

參考函數(shù)原型:

template<class ElemType1逗载,class ElemType2>

void Add_Poly( poly_LinkList<ElemType> &A, poly_LinkList<ElemType> &B, int add_sub );



有序鏈表模板類原型(用于一元多項式計算)參考如下:

/* 單鏈表的結(jié)點定義 */(用于一元多項式計算)

template<class ElemType1, class ElemType2>
struct LinkNode
{
    ElemType1 factor; //系數(shù)
    ElemType2 indice;  //指數(shù)
    LinkNode<ElemType1, ElemType2> *next;
    LinkNode(LinkNode<ElemType1, ElemType2> *ptr = NULL){next = ptr;} //構(gòu)造函數(shù)1,用于構(gòu)造頭結(jié)點
    LinkNode(const ElemType1 &item1, const ElemType1 &item2, LinkNode<ElemType1, ElemType2> *ptr = NULL) //構(gòu)造函數(shù)2况褪,用于構(gòu)造其他結(jié)點  
    //函數(shù)參數(shù)表中的形參允許有默認值,但是帶默認值的參數(shù)需要放后面
    {
        next = ptr;
        factor = item1;
        indice = item2;
    }
    ElemType1 getFactor(){ return factor;}  //取得結(jié)點中的系數(shù)
    ElemType2 getIndice(){ return indice;}  //取得結(jié)點中的指數(shù)
    void SetLink( LinkNode<ElemType1, ElemType2> *link ){ next = link; }  //修改結(jié)點的next域
    void SetFactor( ElemType1 value ){ factor = value; }   //修改結(jié)點的系數(shù)
    void SetIndice( ElemType2 value ){ indice = value; }   //修改結(jié)點的指數(shù)
};

//帶頭結(jié)點的單鏈表(用于一元多項式計算)
template<class ElemType1, class ElemType2>
class poly_LinkList{
   private:
      LinkNode<ElemType1, ElemType2> *head;   // 頭結(jié)點
      LinkNode<ElemType1, ElemType2> *tail;   // 尾結(jié)點
   public:
      //無參數(shù)的構(gòu)造函數(shù)
      poly_LinkList(){head = new LinkNode<ElemType1, ElemType2>;}
      //帶參數(shù)的構(gòu)造函數(shù)
      poly_LinkList(const ElemType1 &item1, const ElemType2 &item2 ){head = new LinkNode<ElemType1, ElemType2>(item1, item2);}
      //拷貝構(gòu)造函數(shù)
      poly_LinkList(poly_LinkList<ElemType1, ElemType2> &List);
      //析構(gòu)函數(shù)
      ~poly_LinkList(){ListDestroy();}
      //銷毀鏈表
      void ListDestroy();
      //清空鏈表
      void ListClear();
      //返回鏈表的長度
      int ListLength() const;
      //判斷鏈表是否為空表
      bool ListEmpty() const;
      //在首節(jié)點之前插入一個結(jié)點
      bool InsFirst( ElemType1 fact, ElemType2 indi );
      //獲取鏈表頭結(jié)點
      LinkNode<ElemType1,ElemType2>* GetHead() { return head;}
      //設(shè)置鏈表頭結(jié)點
      void SetHead(LinkNode<ElemType1,ElemType2> *p){ head = p;}     
      //獲取鏈表尾結(jié)點
      LinkNode<ElemType1,ElemType2>* GetTail() { return tail;}
      //返回鏈表的第i個元素的系數(shù)值
      ElemType1 GetElem_factor(int pos);
      //返回鏈表的第i個元素的指數(shù)值
      ElemType2 GetElem_indice(int pos);
      //在鏈表的第pos個位置之前插入e元素
      bool ListInsert_prior(int pos, ElemType1 fact, ElemType2 indi);
      //在鏈表的第pos個位置之后插入e元素
      bool ListInsert_next(int pos, ElemType1 fact, ElemType2 indi);
      //表頭插入法動態(tài)生成鏈表
      void CreateList_Head(int n, ElemType1 *fact, ElemType2 *indi);     
      //表尾插入法動態(tài)生成鏈表
      void CreateList_Tail(int n, ElemType1 *fact, ElemType2 *indi);    
      //刪除鏈表的第pos個位置的元素
      ElemType2 ListDelete(int pos);
      //按序號查找更耻,從鏈表的第一個結(jié)點開始测垛,判斷當前結(jié)點是否是第i個,
      //若是秧均,則返回該結(jié)點的數(shù)據(jù)域的值食侮;否則繼續(xù)后一個号涯,直至表結(jié)束。沒有第i個結(jié)點時返回空锯七。
      bool FindElem( int k, ElemType1 &fact, ElemType2 &indi);
      //bool compare(ElemType a, ElemType *b);
      //按值查找链快,即定位。從鏈表的第一個結(jié)點開始眉尸,判斷當前結(jié)點值是否等于e域蜗。
      //若是,則返回該結(jié)點的序號噪猾;否則繼續(xù)后一個霉祸,直至表結(jié)束。找不到時返回0袱蜡。
      int SearchElem( const ElemType2 &e) const;
      //返回鏈表給定數(shù)據(jù)元素的后繼數(shù)據(jù)元素的值
      bool NextElem(LinkNode<ElemType1, ElemType2> *p, ElemType1 &fact, ElemType2 &indi);
      //遍歷鏈表
      bool ListTraverse() const;
};

輸入說明 :

第一行:加/減法選擇(0:加法 1:減法)

第二行:一元多項式A的項數(shù)

第三行:一元多項式A的各項的系數(shù)(系數(shù)之間以空格分隔)

第四行:一元多項式A的各項的指數(shù)(指數(shù)之間以空格分隔)

第五行:一元多項式B的項數(shù)

第六行:一元多項式B的各項的系數(shù)(系數(shù)之間以空格分隔)

第七行:一元多項式B的各項的指數(shù)(指數(shù)之間以空格分隔)

輸出說明 :

第一行:多項式A的第一項的系數(shù)丝蹭、指數(shù)(以空格分隔)

第一行:多項式A的第二項的系數(shù)、指數(shù)(以空格分隔)

...

第n行:多項式A的第n項的系數(shù)坪蚁、指數(shù)(以空格分隔) (假設(shè)多項式A的項數(shù)為n)

第一行:多項式B的第一項的系數(shù)奔穿、指數(shù)(以空格分隔)

第一行:多項式B的第二項的系數(shù)、指數(shù)(以空格分隔)

...

第m行:多項式B的第m項的系數(shù)敏晤、指數(shù)(以空格分隔) (假設(shè)多項式B的項數(shù)為m)

第一行:加/減法計算后贱田,結(jié)果多項式A的第一項的系數(shù)、指數(shù)(以空格分隔)

第一行:加/減法計算后茵典,結(jié)果多項式A的第二項的系數(shù)湘换、指數(shù)(以空格分隔)

...

第p行:加/減法計算后,結(jié)果多項式A的第n項的系數(shù)统阿、指數(shù)(以空格分隔) (假設(shè)結(jié)果多項式的項數(shù)為p)

(輸入與輸出之間以空行分隔彩倚,多項式之間以空行分割)

輸入范例 :

1
6
7 3 -22 9 5 -8
0 1 7 8 17 100
3
8 22 -9
1 7 8
輸出范例 :

7 0
3 1
-22 7
9 8
5 17
-8 100

8 1
22 7
-9 8

7 0
-5 1
-44 7
18 8
5 17
-8 100

#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;

/* 單鏈表的結(jié)點定義 */

template<class ElemType1, class ElemType2>
struct LinkNode
{
    ElemType1 factor; //系數(shù)
    ElemType2 indice;  //指數(shù)
    LinkNode<ElemType1, ElemType2>* next;
    LinkNode(LinkNode<ElemType1, ElemType2>* ptr = NULL) { next = ptr; } //構(gòu)造函數(shù)1,用于構(gòu)造頭結(jié)點
    LinkNode( ElemType1& item1,  ElemType1& item2, LinkNode<ElemType1, ElemType2>* ptr = NULL) //構(gòu)造函數(shù)2扶平,用于構(gòu)造其他結(jié)點  
    //函數(shù)參數(shù)表中的形參允許有默認值帆离,但是帶默認值的參數(shù)需要放后面
    {
        next = ptr;
        factor = item1;
        indice = item2;
    }
    ElemType1 getFactor() { return factor; }  //取得結(jié)點中的系數(shù)
    ElemType2 getIndice() { return indice; }  //取得結(jié)點中的指數(shù)
    void SetLink(LinkNode<ElemType1, ElemType2>* link) { next = link; }  //修改結(jié)點的next域
    void SetFactor(ElemType1 value) { factor = value; }   //修改結(jié)點的系數(shù)
    void SetIndice(ElemType2 value) { indice = value; }   //修改結(jié)點的指數(shù)
};

//帶頭結(jié)點的單鏈表(用于一元多項式計算)
template<class ElemType1, class ElemType2>
class poly_LinkList {
private:
    LinkNode<ElemType1, ElemType2>* head = NULL;   // 頭結(jié)點
    LinkNode<ElemType1, ElemType2>* tail = NULL;   // 尾結(jié)點
public:
    //無參數(shù)的構(gòu)造函數(shù)
    poly_LinkList() { head = new LinkNode<ElemType1, ElemType2>; }
    //帶參數(shù)的構(gòu)造函數(shù)
    poly_LinkList( ElemType1& item1,  ElemType2& item2) { head = new LinkNode<ElemType1, ElemType2>(item1, item2); }
    //拷貝構(gòu)造函數(shù)
    poly_LinkList(poly_LinkList<ElemType1, ElemType2>& List);
    //析構(gòu)函數(shù)
    ~poly_LinkList() { ListDestroy(); }
    //銷毀鏈表
    void ListDestroy()
    {
        LinkNode<ElemType1, ElemType2>* p = head;
        while (p != NULL)
        {
            head = p;
            p = p->next;
            delete head;
        }
    }
    //清空鏈表
    void ListClear();
    //返回鏈表的長度
    int ListLength() ;
    //判斷鏈表是否為空表
    bool ListEmpty() ;
    //在首節(jié)點之前插入一個結(jié)點
    bool InsFirst(ElemType1 fact, ElemType2 indi);
    //獲取鏈表頭結(jié)點
    LinkNode<ElemType1, ElemType2>* GetHead() { return head; }
    //設(shè)置鏈表頭結(jié)點
    void SetHead(LinkNode<ElemType1, ElemType2>* p) { head = p; }
    //獲取鏈表尾結(jié)點
    LinkNode<ElemType1, ElemType2>* GetTail() { return tail; }
    //返回鏈表的第i個元素的系數(shù)值
    ElemType1 GetElem_factor(int pos);
    //返回鏈表的第i個元素的指數(shù)值
    ElemType2 GetElem_indice(int pos);
    //在鏈表的第pos個位置之前插入e元素
    bool ListInsert_prior(int pos, ElemType1 fact, ElemType2 indi);
    //在鏈表的第pos個位置之后插入e元素
    bool ListInsert_next(int pos, ElemType1 fact, ElemType2 indi);
    //表頭插入法動態(tài)生成鏈表
    void CreateList_Head(int n, ElemType1* fact, ElemType2* indi);
    //表尾插入法動態(tài)生成鏈表
    void CreateList_Tail(int n, ElemType1* fact, ElemType2* indi)
    {
        LinkNode<ElemType1, ElemType2>* p = head;
        for (int i = 0;i < n;i++)
        {
            tail = new LinkNode<ElemType1, ElemType2>;
            tail->factor = fact[i];
            tail->indice = indi[i];
            p->next = tail;
            p = p->next;
        }
    }
    //刪除鏈表的第pos個位置的元素
    ElemType2 ListDelete(int pos);
    //按序號查找,從鏈表的第一個結(jié)點開始结澄,判斷當前結(jié)點是否是第i個哥谷,
    //若是,則返回該結(jié)點的數(shù)據(jù)域的值麻献;否則繼續(xù)后一個们妥,直至表結(jié)束。沒有第i個結(jié)點時返回空勉吻。
    bool FindElem(int k, ElemType1& fact, ElemType2& indi);
    //bool compare(ElemType a, ElemType *b);
    //按值查找监婶,即定位。從鏈表的第一個結(jié)點開始,判斷當前結(jié)點值是否等于e惑惶。
    //若是煮盼,則返回該結(jié)點的序號;否則繼續(xù)后一個带污,直至表結(jié)束僵控。找不到時返回0。
    int SearchElem( ElemType2& e) ;
    //返回鏈表給定數(shù)據(jù)元素的后繼數(shù)據(jù)元素的值
    bool NextElem(LinkNode<ElemType1, ElemType2>* p, ElemType1& fact, ElemType2& indi);
    //遍歷鏈表
    bool ListTraverse()
    {
        LinkNode<ElemType1, ElemType2>* p = head->next;
        if (p == NULL)return false;
        while (p)
        {
            cout << p->factor << " " << p->indice << endl;
            p = p->next;
        }
        return true;
    }
};

template<class ElemType1,class ElemType2>
void Add_Poly(poly_LinkList<ElemType1,ElemType2>& A, poly_LinkList<ElemType1, ElemType2> & B, int add_sub)
{
    if (add_sub == 0)add_sub = 1;
    else add_sub = -1;
    LinkNode<ElemType1, ElemType2>* pre1 = A.GetHead(), * pre2 = B.GetHead();
    LinkNode<ElemType1, ElemType2>* p = A.GetHead()->next, * q = B.GetHead()->next;
    while (q != NULL)
    {
        if (q->getIndice() == p->getIndice())
        {
            p->SetFactor(p->getFactor() + add_sub * q->getFactor());
            delete pre2;
            pre2 = q;
            q = q->next;
        }
        else if (q->getIndice() < p->getIndice()) 
        {
            delete pre2;
            pre2 = q;
            q = q->next;
            pre1->next = pre2;
            pre2->SetFactor(pre2->getFactor() * add_sub);
            pre2->next = p;
            pre1 = pre2;
        }
        else 
        {
            pre1 = p;
            p = p->next;
        }
    }
    for (pre1 = A.GetHead(), p = pre1->next;p != NULL;)
    {
        if (p->getFactor() == 0)
        {
            pre1->next = p->next;
            delete p;
            p = pre1->next;
            continue;
        }
        pre1 = p, p = p->next;
    }
    B.SetHead(NULL);
}

template<class ElemType1, class ElemType2>
void input(int& n, ElemType1* fact, ElemType2* indi)
{
    cin >> n;
    for (int i = 0;i < n;i++)
        cin >> fact[i];
    for (int i = 0;i < n;i++)
        cin >> indi[i];
}

int main()
{
    typedef int ElemType1;
    typedef int ElemType2;
    int add_sub;
    int n = 0;
    ElemType1 fact[1000];
    ElemType2 indi[1000];
    cin >> add_sub;
    poly_LinkList<ElemType1, ElemType2>A, B;
    input(n, fact, indi);
    A.CreateList_Tail(n, fact, indi);
    input(n, fact, indi);
    B.CreateList_Tail(n, fact, indi);

    A.ListTraverse();
    cout << endl;
    B.ListTraverse();
    cout << endl;
    Add_Poly(A, B, add_sub);
    A.ListTraverse();
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鱼冀,一起剝皮案震驚了整個濱河市报破,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雷绢,老刑警劉巖泛烙,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異翘紊,居然都是意外死亡蔽氨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門帆疟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鹉究,“玉大人,你說我怎么就攤上這事踪宠∽耘猓” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵柳琢,是天一觀的道長绍妨。 經(jīng)常有香客問我,道長柬脸,這世上最難降的妖魔是什么他去? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮倒堕,結(jié)果婚禮上灾测,老公的妹妹穿的比我還像新娘。我一直安慰自己垦巴,他們只是感情好媳搪,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著骤宣,像睡著了一般秦爆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上憔披,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天等限,我揣著相機與錄音,去河邊找鬼。 笑死精刷,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的蔗候。 我是一名探鬼主播怒允,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锈遥!你這毒婦竟也來了纫事?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤所灸,失蹤者是張志新(化名)和其女友劉穎丽惶,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體爬立,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡钾唬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了侠驯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抡秆。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吟策,靈堂內(nèi)的尸體忽然破棺而出儒士,到底是詐尸還是另有隱情,我是刑警寧澤檩坚,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布着撩,位于F島的核電站,受9級特大地震影響匾委,放射性物質(zhì)發(fā)生泄漏拖叙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一剩檀、第九天 我趴在偏房一處隱蔽的房頂上張望憋沿。 院中可真熱鬧,春花似錦沪猴、人聲如沸辐啄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽壶辜。三九已至,卻和暖如春担租,著一層夾襖步出監(jiān)牢的瞬間砸民,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留岭参,地道東北人反惕。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像演侯,于是被迫代替她去往敵國和親姿染。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355