关于多项式的加和、乘积可用链表和数组

本文介绍了使用数组和链表来处理多项式加法和乘法的方法。数组方法适用于连续指数,但不适用于不连续情况。链表方法包括创建、插入、删除节点以及相加和相乘多项式。链表相加存在重复代码,相乘通过遍历最高次幂并反转链表实现。总结了简单的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于多项式的加和、乘积

  • 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

用两种方式创建链表

  1. 第一种 多申请一个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;
}
  1. 此方法更合理
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,总结

方法还有很多,目前只是简单的实现,记录于此!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值