關於多項式的加和、乘積可用連結串列和陣列
文章目錄
關於多項式的加和、乘積
-
Dargon
-
2020/11/11
-
所遇到的的重要的問題:
-
教科書 來自:《資料結構和演算法分析》第三章
對於連結串列操作,自己要去自己實現連結串列的節本功能,例如基本的created、insert、delete。要寫出來,並且執行才知道其中的一些道理,和自己容易出錯的地方
1,運用陣列運算
-
運用陣列儲存對應指數的項的係數
例如對於陣列a[10] 可以儲存0 次方~ 9 次方的係數,陣列的下標對應的是指數,陣列的元素的內容對應的是該位的係數。 -
缺點
當遇到不連續的情況,就事倍功半了 如計算a = X^1000 +5X^10, b = X^1050 +X^1 +5
2,運用連結串列運算
Creat struct:
typedef struct PNODE {
int Coefficient;
int Exponent;
struct PNODE *Next;
}ListNode;
2.1 建立連結串列 Created_linklist
用兩種方式建立連結串列
- 第一種 多申請一個head 浪費一些記憶體空間
ListNode *creat_list(int n) {
ListNode *root;
ListNode *pre, *current;
int c, e, i;
root =(ListNode *)malloc(sizeof(ListNode));
assert(root !=NULL);
pre =root;
for( i =0; i <n; i++ ) {
printf("請輸入第%d項: ", i+1);
scanf("%d%d", &c, &e);
current =(ListNode *)malloc(sizeof(ListNode));
assert( current !=NULL );
current->Coefficient =c;
current->Exponent =e;
current->Next =NULL;
pre->Next =current;
pre =current;
}
return root;
}
- 此方法更合理
ListNode *creat_list_v2(int n) {
ListNode *root;
ListNode *newnode, *current;
int c, e, i;
root =current =NULL;
for(i =0; i <n; i++) {
printf("請輸入第%d項: ", i+1);
scanf("%d%d", &c, &e);
newnode =(ListNode *)malloc(sizeof(ListNode));
assert( newnode != NULL );
newnode->Coefficient =c;
newnode->Exponent =e;
newnode->Next =NULL;
if(root ==NULL)
root =newnode;
else
current->Next =newnode;
current =newnode;
}
return root;
}
2.2 插入節點 insert ListNode
和正常的插入節點一樣,將指向連結串列(根指標root)的指標作為引數傳入到函式中,排除previous =NULL 的特殊情況
int insert_onenode_v2(ListNode **rootp) {
ListNode *current;
ListNode *newnode;
int c, e;
printf("分別輸入要插入項的係數指數:");
scanf("%d%d", &c,&e);
while( (current =*rootp) !=NULL && current->Exponent >e ) {
rootp =&(current->Next);
}
if(current->Exponent ==e) {
current->Exponent +=e;
}
else {
newnode =(ListNode *)malloc(sizeof(ListNode));
assert( newnode !=NULL );
newnode->Coefficient =c;
newnode->Exponent =e;
newnode->Next =current;
*rootp =newnode;
}
return TRUE;
}
2.3 刪除節點 delete ListNode
int delete_onenode(ListNode **rootp) {
ListNode *current;
int e;
printf("分別輸入要刪除項的指數:");
scanf("%d", &e);
while( (current =*rootp) !=NULL && current->Exponent !=e ) {
rootp =&(current->Next);
}
if( current ==NULL ) return FALSE;
else {
*rootp =current->Next;
free(current);
}
return TRUE;
}
2.4 多項式相加 polynomial add
方法有待於更改,傳入的多項式,預設是次冪是從高到低進行排列的,中間重複程式碼過多!!
void product_node(ListNode **rootp, int COE, int e) {
ListNode *newnode;
newnode =(ListNode *)malloc(sizeof(ListNode));
assert(newnode !=NULL);
newnode->Coefficient =COE;
newnode->Exponent =e;
newnode->Next =NULL;
(*rootp)->Next =newnode;
(*rootp) =newnode;
}
ListNode *AddPolynomial_v3( ListNode *roota, ListNode *rootb ) {
ListNode *pa, *pb, *rootc, *pc, *newnode;
pa =roota->Next;
pb =rootb->Next;
rootc =(ListNode *)malloc(sizeof(ListNode));
rootc->Coefficient =0;
rootc->Exponent =0;
rootc->Next =NULL;
pc =rootc;
int COE =0, e;
while( pa !=NULL && pb !=NULL ) {
if(pa->Exponent ==pb->Exponent) {
COE =pa->Coefficient +pb->Coefficient;
e =pa->Exponent;
pa =pa->Next;
pb =pb->Next;
}
else if( pa->Exponent >pb->Exponent ) {
COE =pa->Coefficient;
e =pa->Exponent;
pa =pa->Next;
}
else {
COE =pb->Coefficient;
e =pb->Exponent;
pb =pb->Next;
}
if( COE !=0 ) {
product_node(&pc, COE, e);
COE =0;
}
}
while( pa !=NULL ) {
COE =pa->Coefficient;
e =pa->Exponent;
pa =pa->Next;
if( COE !=0 ) {
product_node(&pc, COE, e);
COE =0;
}
}
while( pb !=NULL ) {
COE =pb->Coefficient;
e =pb->Exponent;
pb =pb->Next;
if( COE !=0 ) {
product_node(&pc, COE, e);
COE =0;
}
}
return rootc;
}
測試結果顯示
int DataStruct_02_02(void) {
ListNode *roota, *rootb;
roota =creat_list_v2(2);
print_list_v2(roota);
rootb =creat_list_v2(2);
print_list_v2(rootb);
insert_onenode_v2( &rootb);
print_list_v2(rootb);
delete_onenode(&rootb);
print_list_v2(rootb);
print_list_v2(AddPolynomial_v2(roota, rootb));
free_list(roota);
free_list(rootb);
return RUN_TEST_OK;
}
result
請輸入第1項: 1 3
請輸入第2項: 2 1
1*X^3+ 2*X^1
請輸入第1項: 1 5
請輸入第2項: 1 3
1*X^5+ 1*X^3
分別輸入要插入項的係數指數:1 6
1*X^6+ 1*X^5+ 1*X^3
分別輸入要刪除項的指數:6
1*X^5+ 1*X^3
1*X^5+ 2*X^3+ 2*X^1
1/1 (100.00%) passed
按任意鍵關閉終端。
2.4 多項式相乘 polynomial multiply
解題思路參照:https://blog.csdn.net/weixin_43911865/article/details/100544395
整體的思路就是:
利用最高次冪去做循壞,每一次迴圈將所有相乘為該次冪的項全部找出,將其係數相乘作和,直到找到 0 次冪為止
中間利用一次反轉,對於整個連結串列的反轉,不過此方法還是做了很多次沒有意義的迴圈。
void inverse_list(ListNode *root) {
ListNode *current =root->Next;
ListNode *next;
root->Next =NULL;
while(current) {
next =current->Next;
current->Next =root->Next;
root->Next =current;
current =next;
}
}
ListNode *MultPolynomial_v2( ListNode *roota, ListNode *rootb ) {
ListNode *rootc, *pa, *pb, *pc, *newnode;
int exp_max;
pa =roota;
pb =rootb;
if(pa->Next !=NULL && pb->Next !=NULL) {
exp_max =pa->Next->Exponent +pb->Next->Exponent;
}
else {
return NULL;
}
rootc =(ListNode *)malloc(sizeof(ListNode));
assert(rootc !=NULL);
rootc->Coefficient =0;
rootc->Exponent =0;
rootc->Next =NULL;
pc =rootc; //As a head of listnode to use
inverse_list(rootb); //Inverse order of the list
int COE =0; //係數和
int k =0; //指數
for(k =exp_max; k >=0; k--) {
//Keep pa exponent is largest
pa =roota->Next;
while(pa !=NULL && pa->Exponent >k) {
pa =pa->Next;
}
//Search pb in the list
pb =rootb->Next;
while(pa !=NULL && pb !=NULL && (pa->Exponent +pb->Exponent) <k) {
pb =pb->Next;
}
// Now (pa +pb)->exp >= k
while(pa !=NULL && pb !=NULL) {
if( (pa->Exponent +pb->Exponent) ==k ) {
COE += (pa->Coefficient *pb->Coefficient);
pa =pa->Next;
pb =pb->Next;
}
else {
if( (pa->Exponent +pb->Exponent) <k )
pb =pb->Next;
else
pa =pa->Next;
}
}
//mallco new node insert in c list
if( COE !=0 ) {
newnode =(ListNode *)malloc(sizeof(ListNode));
assert(newnode);
newnode->Coefficient =COE;
newnode->Exponent =k;
newnode->Next =NULL;
pc->Next =newnode;
pc =newnode;
COE =0;
}
}
inverse_list(rootb);
return rootc;
}
測試結果 result
請輸入第1項: 1 2
請輸入第2項: 1 1
1*X^2+ 1*X^1
請輸入第1項: 1 3
請輸入第2項: 1 1
1*X^3+ 1*X^1
1*X^5+ 1*X^4+ 1*X^3+ 1*X^2
1/1 (100.00%) passed
按任意鍵關閉終端。
2.4 free記憶體
void free_list(ListNode *root) {
ListNode *first_node;
while(root !=NULL) {
first_node =root;
root =root->Next;
free(first_node);
}
}
3,總結
方法還有很多,目前只是簡單的實現,記錄於此!
相關文章
- 陣列和連結串列陣列
- 用單連結串列實現多項式加,減,乘,簡單微分
- 歸併排序:陣列和連結串列的多種實現排序陣列
- day1-陣列和連結串列陣列
- 面試-陣列和連結串列的區別面試陣列
- 陣列與連結串列陣列
- 陣列模擬單連結串列陣列
- 可變陣列——連結串列前言陣列
- 資料結構--陣列、單向連結串列、雙向連結串列資料結構陣列
- 資料結構-棧(通過陣列和單向連結串列實現)資料結構陣列
- Redis筆記 — 連結串列和連結串列節點的API函式(三)Redis筆記API函式
- C/C++ 陣列連結串列表示式計算C++陣列
- 線性結構 陣列與連結串列陣列
- 重溫四大基礎資料結構:陣列、連結串列、佇列和棧資料結構陣列佇列
- 判斷單連結串列是否關於中心對陣
- vue 關於陣列和物件的更新Vue陣列物件
- 【DP】乘積最大子陣列陣列
- java的多項式的加減乘除和賦值Java賦值
- 聊聊陣列與連結串列,棧與佇列陣列佇列
- jquery裡遍歷普通陣列和多維陣列的方法及例項jQuery陣列
- L2-022 重排連結串列【陣列】陣列
- 關於動態連結串列的理解
- 深度理解vue 關於陣列和物件的更新Vue陣列物件
- [redis]SDS和連結串列Redis
- 線性表(陣列、連結串列、佇列、棧)詳細總結陣列佇列
- L2-002 連結串列去重【陣列】陣列
- 【Leetcode】152.乘積最大子陣列LeetCode陣列
- JZ-051-構建乘積陣列陣列
- LeetCode-152-乘積最大子陣列LeetCode陣列
- 【矩陣求導】關於點乘 (哈達瑪積)的矩陣求導矩陣求導點乘
- 重學資料結構和演算法(一)之複雜度、陣列、連結串列、棧、佇列、圖資料結構演算法複雜度陣列佇列
- LeetCode 238. 除自身以外陣列的乘積LeetCode陣列
- LeetCode-238-除自身以外陣列的乘積LeetCode陣列
- 設定連結a可用和不可用
- 陣列模擬雙連結串列,你get到了嗎?陣列
- 陣列模擬單連結串列你會了嗎?陣列
- 資料結構--單連結串列(通過陣列實現)資料結構陣列
- 鏈式佇列—用連結串列來實現佇列佇列