多項式鏈表的結構和接口均參考嚴蔚敏老師的(c語言版)《數據結構》。
指針pa所指結點的指數值 < 指針pb所指結點的指數值:則應摘取pa指針所指結點插入到“和多項式”鏈表中去 指針pa所指結點的指數值 < 指針pb所指結點的指數值:則應摘取pb指針所指結點插入到“和多項式“鏈表中去 指針pa所指結點的指數值 = 指針pb所指結點的指數值:則兩個結點中的系數相加,若和數部位零,pa所指結點的系數值,同時釋放pb所指的結點;反之,從多項式鏈表中刪除相應的結點,同時釋放pa和pb所指向的結點。假設指針pa,pb分別指向多項式A和B當前進行比較的某個結點,則比較這兩個結點的指數項,有下列三種情況:
簡單的思路:先把減數多項式的系數一一取相反數,然後調用加法函數即可實現。
M (
= A(
=
所以,乘法也可以轉換成加法實現。
對於鏈表的操作有幾點需要牢記:
需要對鏈表進行有效性判斷
對於鏈表的操作過程中,首先要創建一個節點,並將頭結點復制給新節點
如果要構建新的鏈表是,表頭需要單獨保存;同時每個節點需要創建新節點,完成賦值、指針操作;組後需要一個游標節點,負責將各個節點串聯起來。 對於尾節點,最後一定要將其next指向NULL。 若在對鏈表操作時不想改變鏈表的值,則需要使用malloc函數重新定義一個鏈表,並把 原鏈表的內容賦給新鏈表。此時切記,不要把原鏈表的指針賦給新生成的結點,否則,在使用的過程中依舊會改變原鏈表,這是因為指針的特性。/* 接口聲明和數據結構聲明頭文件 */ /* 項的表示 * 多項式的項作為單鏈表的數據元素 */ typedef struct{ /* 系數 */ int coef; /* 指數 */ int expn; }datatype; /* 線性單鏈表的存儲結構 */ typedef struct l_node{ /* 數據域表示多項式的項 */ datatype data; /* 指針域 */ struct l_node *next; }l_node,*link_list; /* 用帶頭結點的有序鏈表表示多項式 */ typedef link_list polynomial; #define true 1 #define false 0 /* 定義ccompare函數的返回值 */ #define a_e_b 0 //a = b #define a_g_b 1 //a > b #define a_s_b -1 //a < b /* 定義polyn_locate函數的返回值 */ #define prior -1 //要找元素值不存在且小於鏈表中的某些結點 #define curor 0 //要找元素存在 #define nextor 1 //要找元素值不存在且大於鏈表中的結點 /* -------------------基本操作的函數原型說明------------------- */ /* 比較兩個類型為datatype的變量 * 若a = b,返回a_e_b * 若a > b,返回a_g_b * 若a < b,返回a_s_b */ int compare(datatype a, datatype b); /* 定義polyn_locate函數的返回類型 */ typedef struct{ /* 指向某結點的指針 */ polynomial p; /* 類型 */ int type; }locate; /* 若有序鏈表中HEAD中存在與e滿足判定函數compare()取值為a_e_b的元素 則p為指向HEAD中第一個值為e的結點的指針,並返回curor *若有序鏈表中HEAD中存在與e滿足判定函數compare()取值為a_g_b的元素 則p為指向HEAD中最後一個結點的指針,並返回nextor *若有序鏈表中HEAD中存在與e滿足判定函數compare()取值為a_s_b的元素 則p為指向HEAD中第一個大於e的結點的指針,並返回prior */ locate polyn_locate(polynomial HEAD, datatype e, int(*compare)(datatype, datatype)); /* 按有序判定函數compare()的約定,將值為e的結點插入到有序鏈表的適當位置 */ void polyn_order_insert(polynomial HEAD, datatype e, int(*compare)(datatype, datatype)); /* 輸入m項的系數和指數,建立表示一元多項式的有序鏈表 * HEAD為鏈表的頭指針 */ void polyn_create(polynomial HEAD); /* 銷毀一元多項式 */ void polyn_destroy(polynomial HEAD); /* 打印輸出一個一元多項式 */ void polyn_print(polynomial HEAD); /* 返回一元多項式的項數 */ int polyn_length(polynomial HEAD); /* 完成多項式的相加 * pa = pa + pb * 然後銷毀一元多項式pb */ polynomial polyn_add(polynomial pa, polynomial pb); /* 完成多項式的相減 * pa = pa -pb * 並銷毀一元多項式pb */ polynomial polyn_subtract(polynomial pa, polynomial pb); /* 完成多項式的相乘 * pa = pa * pb * 並銷毀一元多項式pb */ polynomial polyn_multiply(polynomial pa, polynomial pb); /* 復制一個單鏈表 */ polynomial polyn_clone(polynomial HEAD); /* 接口的實現文件 */ #include#include #include"polynomial.h" int compare(datatype a, datatype b) { if(a.expn == b.expn) return a_e_b; if(a.expn > b.expn) return a_g_b; if(a.expn < b.expn) return a_s_b; } void polyn_print(polynomial HEAD) { /* p指向第一個結點 */ polynomial p = HEAD -> next; if(!p) printf("此鏈表為空\n"); else { while(p -> next) { if (p -> next -> data.coef >= 0) printf("%dx^%d + ",p -> data.coef,p -> data.expn); else printf("%dx^%d ",p -> data.coef,p -> data.expn); p = p -> next; } printf("%dx^%d\n",p -> data.coef,p -> data.expn); } } locate polyn_locate(polynomial HEAD, datatype e, int(*compare)(datatype, datatype)) { /* 初始化ptr指向頭指針 */ locate ptr; ptr.p = HEAD; while((ptr.p) -> next) { if(compare( (ptr.p -> next -> data), e) == a_e_b) { ptr.p = ptr.p -> next; ptr.type = curor; return ptr; } if(compare( ptr.p -> next -> data, e) == a_g_b) { ptr.type = prior; return ptr; } if(compare( ptr.p -> next -> data, e) == a_s_b) { ptr.p = ptr.p -> next; } } ptr.type = nextor; return ptr; } void polyn_order_insert(polynomial HEAD, datatype e, int(*compare)(datatype, datatype)) { locate ptr = polyn_locate(HEAD, e, compare); if (ptr.type == nextor) { /* 新建結點 */ polynomial new_node = (polynomial)malloc(sizeof(l_node)); new_node -> data = e; /* 修改指針域 */ ptr.p -> next = new_node; new_node -> next = NULL; } if (ptr.type == prior) { /* 新建結點 */ polynomial new_node = (polynomial)malloc(sizeof(l_node)); new_node -> data = e; /* 修改指針域 */ new_node -> next = ptr.p -> next; ptr.p -> next = new_node; } /* 若該項已存在 */ if (ptr.type == curor) { (ptr.p -> data).coef += e.coef; } } void polyn_create(polynomial HEAD) { /* 初始化頭指針 */ HEAD -> next = NULL; datatype temp; scanf("%d %d",&(temp.coef), &(temp.expn)); /* 系數為零,指數為任意值時退出 */ while(temp.coef != 0) { /* 建立新結點 */ polyn_order_insert(HEAD, temp, compare); scanf("%d %d",&(temp.coef), &(temp.expn)); } } void polyn_destroy(polynomial HEAD) { while(HEAD) { polynomial p = HEAD; HEAD = HEAD -> next; free(p); } } int polyn_length(polynomial HEAD) { polynomial p = HEAD -> next; int i = 0; while(p) { i += 1; p = p -> next; } return i; } polynomial polyn_add(polynomial pa, polynomial pb) { /* 和鏈表的頭結點 */ polynomial hc = pa; /* 指向和鏈表的最後一個結點 */ polynomial pc = hc; /* hb為鏈表b的頭結點 */ polynomial hb = pb; /* 當前結點 */ pb = pb -> next; /* 當前結點 */ pa = pa -> next; int type; while(pa && pb) { type = compare(pa -> data, pb -> data); if (type == a_e_b) { /* 指數相同,系數相加 */ (pa -> data).coef = (pa -> data).coef + (pb -> data).coef; if (pa -> data.coef == 0) { /* 刪除pa的當前結點 */ pc -> next = pa; pa = pa -> next; free(pc -> next); pc -> next = NULL; /* 刪除pb的當前結點 */ hb -> next = pb -> next; free(pb); pb = hb -> next; } else { /* 將結點存至和鏈 */ pc -> next = pa; pc = pa; /* 改變b的頭結點 */ hb -> next = pb -> next; /* 釋放當前結點 */ free(pb); /* 下一個結點 */ pb = hb -> next; /* 下一個結點 */ pa = pa -> next; } } if (type == a_s_b) { /* 將結點存至和鏈 */ pc -> next = pa; pc = pa; pa = pa -> next; } if (type == a_g_b) { /* 將b鏈的當前結點存至和鏈 */ pc -> next = pb; pc = pb; pb = pb -> next; hb -> next = pb; } } if(pa == NULL) { if(pb == NULL) free(hb); else { pc -> next = pb; free(hb); } } else { free(hb); pc -> next = pa; } return hc; } polynomial polyn_subtract(polynomial pa, polynomial pb) { /* 先把pb鏈(減數)取負,然後調用加法函數即可 */ polynomial hb = pb -> next; while(hb) { hb -> data.coef = 0 - (hb -> data.coef); hb = hb -> next; } polynomial pc = polyn_add(pa, pb); return pc; } polynomial polyn_multiply(polynomial pa, polynomial pb) { /* 積的頭結點 */ polynomial p =(polynomial)malloc(sizeof(l_node)); p -> next = NULL; /* 被乘數的當前結點 */ polynomial pac = pa -> next; /* 乘數的當前結點 */ polynomial pbc = pb -> next; while(pbc) { /* 中間鏈的頭結點 */ polynomial pc = polyn_clone(pa); /* 中間鏈的當前結點 */ polynomial pcc = pc -> next; while(pac) { pcc -> data.coef = (pac -> data.coef) * (pbc -> data.coef); pcc -> data.expn = (pac -> data.expn) + (pbc -> data.expn); pcc = pcc -> next; pac = pac -> next; } pac = pa -> next; p = polyn_add(p, pc); pbc = pbc -> next; } polyn_destroy(pa); polyn_destroy(pb); return p; } polynomial polyn_clone(polynomial HEAD) { /* 源鏈的當前結點 */ polynomial pnode = HEAD; /* 目的鏈的頭結點和當前結點 */ polynomial pclone_head,pclone_node; if(pnode != NULL) { pclone_head = (polynomial)malloc(sizeof(l_node)); pclone_head -> data = pnode -> data; pclone_head -> next = NULL; pclone_node = pclone_head; pnode = pnode -> next; } while(pnode != NULL) { polynomial temp_node = (polynomial)malloc(sizeof(l_node)); temp_node -> data = pnode -> data; temp_node -> next = NULL; pclone_node -> next = temp_node; pclone_node = pclone_node -> next; pnode = pnode -> next; } return pclone_head; } int main() { /* 創建pa鏈表 */ polynomial pa = (polynomial)malloc(sizeof(l_node)); polyn_create(pa); /* 打印pa鏈表 */ polyn_print(pa); /* 創建pb鏈表 */ polynomial pb = (polynomial)malloc(sizeof(l_node)); polyn_create(pb); /* 打印pb鏈表 */ polyn_print(pb); /* 兩個多項式相乘 */ polynomial p = polyn_multiply(pa, pb); /* 打印結果 */ polyn_print(p); /* 乘積的長度 */ printf("length=%d\n", polyn_length(p)); return 0; }