c语言单链表实现多项式计算

多项式链表的结构和接口均参考严蔚敏老师的(c语言版)《数据结构》。

加法的实现:

假设指针pa,pb分别指向多项式A和B当前进行比较的某个结点,则比较这两个结点的指数项,有下列三种情况:

  1. 指针pa所指结点的指数值 < 指针pb所指结点的指数值:则应摘取pa指针所指结点插入到“和多项式”链表中去
  2. 指针pa所指结点的指数值 < 指针pb所指结点的指数值:则应摘取pb指针所指结点插入到“和多项式“链表中去
  3. 指针pa所指结点的指数值 = 指针pb所指结点的指数值:则两个结点中的系数相加,若和数部位零,pa所指结点的系数值,同时释放pb所指的结点;反之,从多项式链表中删除相应的结点,同时释放pa和pb所指向的结点。

减法的实现:

简单的思路:先把减数多项式的系数一一取相反数,然后调用加法函数即可实现。

乘法的实现:

M ( x ) = A(x) x B( x ) 
    = A(x) x [ b1xe1+b2xe2...+bnxen ]
    = ni=1biA(x)xei

所以,乘法也可以转换成加法实现。

对于链表的操作有几点需要牢记:

  1. 需要对链表进行有效性判断

  2. 对于链表的操作过程中,首先要创建一个节点,并将头结点复制给新节点

  3. 如果要构建新的链表是,表头需要单独保存;同时每个节点需要创建新节点,完成赋值、指针操作;组后需要一个游标节点,负责将各个节点串联起来。
  4. 对于尾节点,最后一定要将其next指向NULL。
  5. 若在对链表操作时不想改变链表的值,则需要使用malloc函数重新定义一个链表,并把 原链表的内容赋给新链表。此时切记,不要把原链表的指针赋给新生成的结点,否则,在使用的过程中依旧会改变原链表,这是因为指针的特性。

c语言代码实现

/* 接口声明和数据结构声明头文件 */

/* 项的表示 
 * 多项式的项作为单链表的数据元素
*/
typedef struct{
    /* 系数 */
    int coef;
    /* 指数 */
    int expn;
}datatype;

/* 线性单链表的存储结构 */
typedef struct l_node{
    /* 数据域表示多项式的项 */
    datatype data;
    /* 指针域 */
    struct l_node *next;
}l_node,*link_list;

/* 用带头结点的有序链表表示多项式 */
typedef link_list polynomial;

#define true 1
#define false 0

/* 定义ccompare函数的返回值 */
#define a_e_b 0  //a = b
#define a_g_b 1  //a > b
#define a_s_b -1 //a < b


/* 定义polyn_locate函数的返回值 */
#define prior -1  //要找元素值不存在且小于链表中的某些结点
#define curor 0   //要找元素存在
#define nextor 1  //要找元素值不存在且大于链表中的结点


/* -------------------基本操作的函数原型说明------------------- */



/* 比较两个类型为datatype的变量
 * 若a = b,返回a_e_b
 * 若a > b,返回a_g_b
 * 若a < b,返回a_s_b
*/
int compare(datatype a, datatype b);


/* 定义polyn_locate函数的返回类型 */
typedef struct{
    /* 指向某结点的指针 */
    polynomial p;
    /* 类型 */
    int type;
}locate;

/* 若有序链表中HEAD中存在与e满足判定函数compare()取值为a_e_b的元素
 则p为指向HEAD中第一个值为e的结点的指针,并返回curor

 *若有序链表中HEAD中存在与e满足判定函数compare()取值为a_g_b的元素
 则p为指向HEAD中最后一个结点的指针,并返回nextor

 *若有序链表中HEAD中存在与e满足判定函数compare()取值为a_s_b的元素
 则p为指向HEAD中第一个大于e的结点的指针,并返回prior
*/
locate polyn_locate(polynomial HEAD, datatype e, int(*compare)(datatype, datatype));

/* 按有序判定函数compare()的约定,将值为e的结点插入到有序链表的适当位置
*/
void polyn_order_insert(polynomial HEAD, datatype e, int(*compare)(datatype, datatype));

/* 输入m项的系数和指数,建立表示一元多项式的有序链表 
 * HEAD为链表的头指针
*/
void polyn_create(polynomial HEAD);

/* 销毁一元多项式 */
void polyn_destroy(polynomial HEAD);

/* 打印输出一个一元多项式 */
void polyn_print(polynomial HEAD);

/* 返回一元多项式的项数 */
int polyn_length(polynomial HEAD);

/* 完成多项式的相加
 * pa = pa + pb
 * 然后销毁一元多项式pb
*/
polynomial polyn_add(polynomial pa, polynomial pb);

/* 完成多项式的相减
 * pa = pa -pb
 * 并销毁一元多项式pb
*/
polynomial polyn_subtract(polynomial pa, polynomial pb);

/* 完成多项式的相乘
 * pa = pa * pb
 * 并销毁一元多项式pb
*/
polynomial polyn_multiply(polynomial pa, polynomial pb);



/* 复制一个单链表 */
polynomial polyn_clone(polynomial HEAD);




/* 接口的实现文件 */
#include<stdio.h>
#include<stdlib.h>
#include"polynomial.h"




int compare(datatype a, datatype b)
{
    if(a.expn == b.expn)
        return a_e_b;
    if(a.expn > b.expn)
        return a_g_b;
    if(a.expn < b.expn)
        return a_s_b;
}


void polyn_print(polynomial HEAD)
{
    /* p指向第一个结点 */
    polynomial p = HEAD -> next;
    if(!p)
        printf("此链表为空\n");
    else
    {
        while(p -> next)
        {
            if (p -> next -> data.coef >= 0)
                printf("%dx^%d + ",p -> data.coef,p -> data.expn);
            else
                printf("%dx^%d ",p -> data.coef,p -> data.expn);   

            p = p -> next;
        }
        printf("%dx^%d\n",p -> data.coef,p -> data.expn);
    }

}


locate polyn_locate(polynomial HEAD, datatype e, int(*compare)(datatype, datatype))
{
    /* 初始化ptr指向头指针 */
    locate ptr; 
    ptr.p = HEAD;
    while((ptr.p) -> next)
    {
        if(compare( (ptr.p -> next -> data), e) == a_e_b)
        {
            ptr.p = ptr.p -> next;
            ptr.type = curor;
            return ptr;
        }
        if(compare( ptr.p -> next -> data, e) == a_g_b)
        {
            ptr.type = prior;
            return ptr;
        }
        if(compare( ptr.p -> next -> data, e) == a_s_b)
        {
            ptr.p = ptr.p -> next;
        }
    }
    ptr.type = nextor;
    return ptr;
}




void polyn_order_insert(polynomial HEAD, datatype e, int(*compare)(datatype, datatype))
{

    locate ptr = polyn_locate(HEAD, e, compare);
    if (ptr.type == nextor)
    {
        /* 新建结点 */
        polynomial new_node = (polynomial)malloc(sizeof(l_node));
        new_node -> data = e;
        /* 修改指针域 */
        ptr.p -> next = new_node;
        new_node -> next = NULL;
    }
    if (ptr.type == prior)
    {
        /* 新建结点 */
        polynomial new_node = (polynomial)malloc(sizeof(l_node));
        new_node -> data = e;
        /* 修改指针域 */
        new_node -> next = ptr.p -> next;
        ptr.p -> next = new_node;
    }
    /* 若该项已存在 */
    if (ptr.type == curor)
    {
        (ptr.p -> data).coef += e.coef;
    }
}


void polyn_create(polynomial HEAD)
{
    /* 初始化头指针 */
    HEAD -> next = NULL;
    datatype temp;
    scanf("%d %d",&(temp.coef), &(temp.expn));
    /* 系数为零,指数为任意值时退出 */
    while(temp.coef != 0)
    {
        /* 建立新结点 */
        polyn_order_insert(HEAD, temp, compare);
        scanf("%d %d",&(temp.coef), &(temp.expn));
    }
}

void polyn_destroy(polynomial HEAD)
{
    while(HEAD)
    {
        polynomial p = HEAD;
        HEAD = HEAD -> next;
        free(p);
    }
}


int polyn_length(polynomial HEAD)
{
    polynomial p = HEAD -> next;
    int i = 0;
    while(p)
    {
        i += 1;
        p = p -> next;
    }
    return i;

}

polynomial polyn_add(polynomial pa, polynomial pb)
{ 
    /* 和链表的头结点 */
    polynomial hc = pa;
    /* 指向和链表的最后一个结点 */
    polynomial pc = hc;
    /* hb为链表b的头结点 */
    polynomial hb = pb;
    /* 当前结点 */
    pb = pb -> next;
    /* 当前结点 */
    pa = pa -> next;
    int type;
    while(pa && pb)
    {
        type = compare(pa -> data, pb -> data);
        if (type == a_e_b)
        {
            /* 指数相同,系数相加 */
            (pa -> data).coef = (pa -> data).coef + (pb -> data).coef;
            if (pa -> data.coef == 0)
            {
                /* 删除pa的当前结点 */
                pc -> next = pa;
                pa = pa -> next;
                free(pc -> next);
                pc -> next = NULL;
                /* 删除pb的当前结点 */
                hb -> next = pb -> next;
                free(pb);
                pb = hb -> next;

            }
            else
            {
                /* 将结点存至和链 */
                pc -> next = pa;
                pc = pa;
                /* 改变b的头结点 */
                hb -> next  = pb -> next;
                /* 释放当前结点 */
                free(pb);
                /* 下一个结点 */
                pb = hb -> next; 
                /* 下一个结点 */
                pa = pa -> next;
            }
        }
        if (type == a_s_b)
        {
            /* 将结点存至和链 */
            pc -> next = pa;
            pc = pa;
            pa = pa -> next;
        }
        if (type == a_g_b)
        {
            /* 将b链的当前结点存至和链 */
            pc -> next = pb;
            pc = pb;
            pb = pb -> next;
            hb -> next = pb;
        }
    }

    if(pa == NULL)
    {
        if(pb == NULL)
            free(hb);
        else
        {
            pc -> next = pb;
            free(hb);
        }
    }
    else
    {
        free(hb);
        pc -> next = pa;
    }
    return hc;

}

polynomial polyn_subtract(polynomial pa, polynomial pb)
{
    /* 先把pb链(减数)取负,然后调用加法函数即可 */
    polynomial hb = pb -> next;
    while(hb)
    {
        hb -> data.coef = 0 - (hb -> data.coef);
        hb = hb -> next;     
    }
    polynomial pc = polyn_add(pa, pb);
    return pc;
}

polynomial polyn_multiply(polynomial pa, polynomial pb)
{
    /* 积的头结点 */
    polynomial p =(polynomial)malloc(sizeof(l_node));
    p -> next = NULL;
    /* 被乘数的当前结点 */
    polynomial pac = pa -> next;
    /* 乘数的当前结点 */
    polynomial pbc = pb -> next;
    while(pbc)
    {
        /* 中间链的头结点 */
        polynomial pc = polyn_clone(pa);
        /* 中间链的当前结点 */
        polynomial pcc = pc -> next;
        while(pac)
        {
            pcc -> data.coef = (pac -> data.coef) * (pbc -> data.coef);
            pcc -> data.expn = (pac -> data.expn) + (pbc -> data.expn);
            pcc = pcc -> next;
            pac = pac -> next;
        }
        pac = pa -> next;
        p = polyn_add(p, pc);
        pbc = pbc -> next;
    }
    polyn_destroy(pa);
    polyn_destroy(pb);
    return p;
}


polynomial polyn_clone(polynomial HEAD)
{
    /* 源链的当前结点 */
    polynomial pnode  = HEAD;
    /* 目的链的头结点和当前结点 */
    polynomial pclone_head,pclone_node;
    if(pnode != NULL)
    {
        pclone_head = (polynomial)malloc(sizeof(l_node));
        pclone_head -> data = pnode -> data;
        pclone_head -> next = NULL;
        pclone_node = pclone_head;
        pnode = pnode -> next;
    }
    while(pnode != NULL)
    {
        polynomial temp_node = (polynomial)malloc(sizeof(l_node));
        temp_node -> data = pnode -> data;
        temp_node -> next = NULL;
        pclone_node -> next = temp_node;
        pclone_node = pclone_node -> next;
        pnode = pnode -> next;
    }
    return pclone_head;
}

int main()
{
    /* 创建pa链表 */
    polynomial pa = (polynomial)malloc(sizeof(l_node));
    polyn_create(pa);
    /* 打印pa链表 */
    polyn_print(pa);
    /* 创建pb链表 */
    polynomial pb = (polynomial)malloc(sizeof(l_node));
    polyn_create(pb);
    /* 打印pb链表 */
    polyn_print(pb);
    /* 两个多项式相乘 */
    polynomial p = polyn_multiply(pa, pb);
    /* 打印结果 */
    polyn_print(p);
    /* 乘积的长度 */
    printf("length=%d\n", polyn_length(p));
    return 0;
}
  • 9
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言链表是通过指针实现的数据结构,每个节点包含一个数据元素和一个指向下一个节点的指针。链表可以用于存储任意类型的数据结构,包括一元多项式。 在用单链表存储一元多项式时,每个节点可以表示一个项,包含两个元素:系数和指数。链表的头节点可以表示多项式本身,包含一个指向第一个项的指针。 实现一元多项式计算时,可以通过遍历链表,将相同次数的项合并,得到新的多项式。具体实现可以使用循环或递归算法,遍历链表并进行计算。 以下是一个简单单链表实现一元多项式计算的示例代码: ```c #include <stdio.h> #include <stdlib.h> // 定义一元多项式项的结构体 typedef struct node { float coef; // 系数 int exp; // 指数 struct node* next; // 指向下一个节点的指针 } Term; // 定义一元多项式的结构体 typedef struct { Term* head; // 指向第一个项的指针 } Polynomial; // 创建一元多项式 Polynomial create_polynomial() { Polynomial poly; poly.head = NULL; return poly; } // 在一元多项式中插入一项 void insert_term(Polynomial* poly, float coef, int exp) { Term* term = (Term*)malloc(sizeof(Term)); term->coef = coef; term->exp = exp; term->next = NULL; if (poly->head == NULL) { poly->head = term; } else { Term* p = poly->head; while (p->next != NULL) { p = p->next; } p->next = term; } } // 遍历一元多项式并打印 void print_polynomial(Polynomial poly) { Term* p = poly.head; while (p != NULL) { printf("%.2fx^%d ", p->coef, p->exp); if (p->next != NULL) { printf("+ "); } p = p->next; } printf("\n"); } // 计算一元多项式的值 float evaluate_polynomial(Polynomial poly, float x) { float result = 0; Term* p = poly.head; while (p != NULL) { result += p->coef * pow(x, p->exp); p = p->next; } return result; } // 合并一元多项式 Polynomial merge_polynomial(Polynomial poly1, Polynomial poly2) { Polynomial result = create_polynomial(); Term *p1 = poly1.head, *p2 = poly2.head; while (p1 != NULL && p2 != NULL) { if (p1->exp > p2->exp) { insert_term(&result, p1->coef, p1->exp); p1 = p1->next; } else if (p1->exp < p2->exp) { insert_term(&result, p2->coef, p2->exp); p2 = p2->next; } else { insert_term(&result, p1->coef + p2->coef, p1->exp); p1 = p1->next; p2 = p2->next; } } while (p1 != NULL) { insert_term(&result, p1->coef, p1->exp); p1 = p1->next; } while (p2 != NULL) { insert_term(&result, p2->coef, p2->exp); p2 = p2->next; } return result; } int main() { Polynomial poly1 = create_polynomial(); insert_term(&poly1, 2, 3); insert_term(&poly1, -3, 2); insert_term(&poly1, 1, 0); printf("Poly1: "); print_polynomial(poly1); Polynomial poly2 = create_polynomial(); insert_term(&poly2, -4, 3); insert_term(&poly2, 3, 1); insert_term(&poly2, 2, 0); printf("Poly2: "); print_polynomial(poly2); Polynomial poly3 = merge_polynomial(poly1, poly2); printf("Poly3: "); print_polynomial(poly3); float result = evaluate_polynomial(poly3, 2); printf("Result: %.2f\n", result); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值