多項式的相加
一、案例分析
假如說我們現在有下面兩個多項式:
①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; }
三、運行結果
如有什么不對的地方,歡迎大家指正!