Polynomial 一元多項式的表示及相加 (線性連結串列實現 嚴蔚敏版)
阿新 • • 發佈:2019-02-02
1、貼程式碼:
#include <iostream> #include <cstdio> using namespace std; struct Node { double coef; int expn; Node *next; }; void CreatPolynomial(Node *&head, int n) // 生成帶表頭結點的單鏈表,除頭結點外另生成n個結點 { head = (Node *)malloc(sizeof(Node)); head->coef = 0; head->expn = 0; head->next = NULL; // 初始化頭結點 cout << "請輸入各項係數及指數:" << endl; Node *p = head; for(int i = 0; i < n; i++) { p->next = (Node *)malloc(sizeof(Node)); // 生成新結點,尾插入生成連結串列 p = p->next; cin >> p->coef >> p->expn; p->next = NULL; } } void PrintPolynomial(Node *&head) { if(head->next == NULL) // 結果是0時直接輸出0 putchar('0'); else { for(Node *p = head->next; p != NULL; p = p->next) { if(p != head->next && p->coef >0) // 當p非首項且指向的係數為正時才輸出'+' putchar('+'); // 之前只判定了p->coef >0 if(p->coef == 1) { // 係數為1或-1時特殊處理 if(p->expn == 0) putchar('1'); // 判斷條件不能寫在一起: } // if(p->coef == 1 && p->expn == 0) putchar('1'); else if(p->coef == -1) putchar('-'); else cout << p->coef; switch(p->expn) { // 指數為0或1時特殊處理 case 0: break; case 1: putchar('x'); break; default: p->expn < 0 ? printf("x^(%d)", p->expn) : printf("x^%d", p->expn); // 指數小於0時打括號 break; } } } cout << endl; } // 上面的函式中若係數為int型,那麼也可以改為switch結構,這是C語言的缺陷? void Free(Node *&head) { Node *q = NULL; for(Node *p = head; p != NULL; p = q) { q = p->next; free(p); } } char cmp(int a, int b) { if(a > b) return '>'; if(a < b) return '<'; return '='; } void AddPolynomial(Node *&pA, Node *&pB) // 傳進兩個連結串列的頭指標 { Node *ha = pA; Node *hb = pB; Node *qa = ha->next; // ha, hb分別跟在qa, qb的後一位置 Node *qb = hb->next; // qa, qb分別指向Pa, Pb中當前比較元素 while(qa && qb) { double sum = 0; int a = qa->expn; int b = qb->expn; switch( cmp(a, b) ) { case '<': ha = qa; qa = qa->next; // 非ha = ha->next; break; case '=': sum = qa->coef + qb->coef; if(sum != 0.0) { qa->coef = sum; ha = qa; } else { if(ha->next != qa) cout << "Error: ha->next != qa" << endl; ha->next = ha->next->next; // 刪除和為0的結點,ha不變,還在qa後一位置 free(qa); } if(hb->next != qb) cout << "Error: hb->next != qb" << endl; hb->next = hb->next->next; free(qb); qb = hb->next; qa = ha->next; break; case '>': hb->next = hb->next->next; // 刪除qb指向的結點 qb->next = ha->next; // 將qb插入ha後qa前 ha->next = qb; qb = hb->next; // not qb = ha->next ha = ha->next; break; default: cout << "Error!" << endl; break; } } if(qb) ha->next = qb; free(hb); } int main(void) { // freopen("cin.txt", "r", stdin); Node *A = NULL; Node *B = NULL; int lenA; int lenB; while(cout << "請輸入A的項數:" << endl, cin >> lenA) { CreatPolynomial(A, lenA); // 生成A連結串列 cout << "請輸入B的項數:" << endl; // 生成B連結串列 cin >> lenB; CreatPolynomial(B, lenB); cout << " A = "; // 輸出A連結串列 PrintPolynomial(A); cout << " B = "; // 輸出B連結串列 PrintPolynomial(B); AddPolynomial(A, B); // A = A + B cout << "A+B= "; PrintPolynomial(A); // 輸出和 cout << endl; Free(A); // 務必釋放結點 } return 0; }
2、執行:
附一些寶貴的測試資料:
5
-2 -1
-3 0
8 1
3 5
-2 7
5
4 -1
6 0
3 5
1 7
1 8
3
2 1
5 8
-3.1 11
3
7 0
-5 8
11 9
4
6 -3
-1 1
4.4 2
-1.2 9
3
6 -3
-4.4 2
-7.8 15
6
1 0
1 1
1 2
1 3
1 4
1 5
2
-1 3
-1 4
2
1 1
1 3
2
-1 1
-1 3
2
1 1
1 100
2
1 100
1 200
3
1 1
1 2
1 3
0
以上資料的執行結果:
3、想法:
1)那個函式完全對著書寫的,不過之前吃了些苦頭。用帶頭結點的連結串列好啊!(針對本題,不然首項的那些特殊情況要煩死人。)
2)在輸出上花了些工夫,不過還怕有些小錯誤,之前也想了很多情況,夠複雜的了!
2012/5/1更新:
程式碼中“初始化”結構體可用memset