引言
符号多项式的操作,已经成为表处理的典型用例。用一个长度为m且每个元素有两个数据项(系数项和指数项)的线性表((p1,e1), (p2,e2), ···,(pm, em))便可唯一确定多项式Pn(x)。
对应于线性表的两种存储结构,上述定义的一元多项式也可以有两种存储表示方法。由于多项式多进行相加、乘法等操作,因此采用链式存储结构,节约结点插入、删除等操作时间。
元素定义
typedef struct{
float coef; // 项的系数
int exp; // 项的指数
}ElemType; // 多项式的项
一元多项式定义
typedef struct PNode{
ElemType data; // 数据项
struct PNode *next; // 指向后继元素
}PNode, *Polynomail; // 带头结点的链表表示多项式
基本操作
#include
#include
#include
#define SUCCESS 1
#define FAILURE 0
// 定义多项式数据元素
typedef struct{
float coef; // 项的系数
int exp; // 项的指数
} ElemType;
int compare(ElemType e1, ElemType e2){
// 依e1的指数值<(或=)(或>)e2的指数值,分别返回-1,0和1
if(e1.exp < e2.exp){
return -1;
} else if(e1.exp == e2.exp){
return 0;
} else {
return 1;
}
}
typedef struct PNode{
ElemType data;
struct PNode *next;
}PNode, *Polynomail; // 带头结点的有序链表表示多项式
// 基本操作
int InitPolyn(Polynomail *P){
// 初始化P
*P = (Polynomail)malloc(sizeof(PNode));
if(!*P) exit(-1);
(*P)->next = NULL;
}
int LocatePolyn(Polynomail P, ElemType e, int(*compare)(ElemType, ElemType)){
// 在P中寻找和e满足compare结果为0的元素,成功返回1,否则返回-1
P = P->next;
while(P){
if(compare(P->data, e) == 0) return 1;
P = P->next;
}
return -1; // 没有找到
}
void CreatPolyn(Polynomail *P, int m){
// 输入m项系数和指数,建立表示一元多项式的有序链表P
printf("请输入%d项系数和参数, 格式:\ncoef exp\n", m);
Polynomail head = *P;
PNode *s;
head->data.coef = 0.0; head->data.exp = -1; // 头结点
int i;
for(i=0;idata.coef), &(s->data.exp));
if(LocatePolyn(*P, s->data, compare) < 0) { // 排除相同指数项
s->next = NULL;
head->next = s;
head = s;
i++;
}
}
}
void DestroyPolyn(Polynomail *P){
// 销毁一元多项式P
Polynomail s = *P;
Polynomail t;
while(s){
t = s->next;
free(s);
s = t;
}
*P = NULL;
}
void PrintPolyn(Polynomail P){
// 打印输出一元多项式
P = P->next;
int i = 1;
if(P) printf("%.2fx^%d", P->data.coef, P->data.exp);
P = P->next;
while(P){
printf("%+.2fx^%d", P->data.coef, P->data.exp);
P = P->next;
}
printf("\n");
}
int PolynLength(Polynomail P){
// 返回一元多项式P的项数
int l = 0;
P = P->next;
while(P){
l++;
P = P->next;
}
return l;
}
void AddPolyn(Polynomail *Pa, Polynomail *Pb,
int(*compare)(ElemType, ElemType)){
// 完成有序多项式相加运算,即Pa = Pa + pb; 并销毁Pb
Polynomail heada = *Pa, headb = *Pb;
Polynomail headc = heada;
Polynomail temp; // 释放节点时使用
heada = heada->next; // 指向首元素
headb = headb->next;
while(heada && headb){
if(compare(heada->data, headb->data) < 0){
// 当前heada节点指数小于headb
headc->next = heada;
headc = heada;
heada = heada->next;
} else if(compare(heada->data, headb->data) > 0){
// 当前heada节点指数大于headb
headc->next = headb;
headc = headb;
headb = headb->next;
} else{
// 两者节点指数相同
if(heada->data.coef + headb->data.coef != 0){
heada->data.coef = heada->data.coef +
headb->data.coef;
headc->next = heada;
headc = heada;
heada = heada->next;
} else {
temp = heada;
heada = heada->next;
free(temp);
}
temp = headb;
headb = headb->next;
free(temp);
}
}
if(headb) headc->next = headb; // 链接Pb中剩余节点
free(*Pb); // 释放Pb头结点
}
void MultiplyPolyn(Polynomail Pa, Polynomail Pb, Polynomail *Pc){
// 完成多项式相乘运算,即Pc = Pa * Pb
Polynomail pa, pb, s;
// 临时链表
Polynomail temp, headtemp;
pa = Pa->next;
while(pa){
InitPolyn(&temp);
headtemp = temp;
pb = Pb->next; // 每次需将pb重置
while(pb){ // pa同pb中每项相乘并将结果存在pc中
s = (Polynomail)malloc(sizeof(PNode));
s->data.coef = pa->data.coef * pb->data.coef;
s->data.exp = pa->data.exp + pb->data.exp;
s->next = NULL;
headtemp->next = s;
headtemp = s;
pb = pb->next;
}
// 将每次乘积结果相加存储至Pc中
AddPolyn(Pc,&temp, compare);
pa = pa->next;
}
}
void main(){
Polynomail P;
// 初始化
printf("******** init ********\n");
InitPolyn(&P);
// 赋值
printf("********* create value **************\n");
CreatPolyn(&P, 6);
// 打印
printf("********* console value **********\n");
PrintPolyn(P);
// 长度
printf("*************** length **************\n");
printf("P length is: %d\n", PolynLength(P));
//销毁
printf("*************** destroy **************\n");
DestroyPolyn(&P);
printf("after destory, P postion is: %p\n", P);
// 多项式相加
printf("********** polyn add ******************\n");
Polynomail P1, P2;
InitPolyn(&P1); InitPolyn(&P2);
CreatPolyn(&P1, 5); CreatPolyn(&P2, 6);
printf("P1: ");
PrintPolyn(P1);
printf("P2: ");
PrintPolyn(P2);
printf("\n");
AddPolyn(&P1, &P2, compare);
printf("After add, P1: ");
PrintPolyn(P1);
printf("\n");
// 多项式相乘
printf("************ polynnomail multi********\n");
Polynomail P3, P4, P5;
InitPolyn(&P3); InitPolyn(&P4), InitPolyn(&P5);
CreatPolyn(&P3, 4); CreatPolyn(&P4, 3);
printf("P3: ");
PrintPolyn(P3);
printf("P4: ");
PrintPolyn(P4);
printf("\n");
MultiplyPolyn(P3, P4, &P5);
printf("After multi, P5: ");
PrintPolyn(P5);
printf("\n");
}
运行结果
******** init ********
********* create value **************
请输入6项系数和参数, 格式:
coef exp
1 0
-2 1
4 3
6.2 5
-10.4 29
16 356
********* console value **********
1.00x^0-2.00x^1+4.00x^3+6.20x^5-10.40x^29+16.00x^356
*************** length **************
P length is: 6
*************** destroy **************
after destory, P postion is: (nil)
********** polyn add ******************
请输入5项系数和参数, 格式:
coef exp
1 0
-9 5
3 7
5 8
10 10
请输入6项系数和参数, 格式:
coef exp
3 0
9 2
9 5
-4.2 7
1 8
-15 12
P1: 1.00x^0-9.00x^5+3.00x^7+5.00x^8+10.00x^10
P2: 3.00x^0+9.00x^2+9.00x^5-4.20x^7+1.00x^8-15.00x^12
After add, P1: 4.00x^0+9.00x^2-1.20x^7+6.00x^8+10.00x^10-15.00x^12
*********** polynnomail multi********
请输入4项系数和参数, 格式:
coef exp
9 0
-10 1
7 2
6 3
请输入3项系数和参数, 格式:
coef exp
-5 0
4 1
-2 3
P3: 9.00x^0-10.00x^1+7.00x^2+6.00x^3
P4: -5.00x^0+4.00x^1-2.00x^3
After multi, P5: -45.00x^0+86.00x^1-75.00x^2-20.00x^3+44.00x^4-14.00x^5-12.00x^6