文章目录
关于多项式的加和、乘积
-
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.youkuaiyun.com/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,总结
方法还有很多,目前只是简单的实现,记录于此!