线性表(三)一元多项式应用

引言

符号多项式的操作,已经成为表处理的典型用例。用一个长度为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

你可能感兴趣的:(线性表(三)一元多项式应用)