一元不等式的乘法和加法

#include<stdio.h>///选择链表的原因:方便插入和删除
#include<stdlib.h>///exit函数的声明在这个头文件里
typedef struct Node
{
    int coefficient; //系数
    int exponent;    //指数
    struct Node *next;  ///该结构体类型的指针     
} Node;   ///该Node是struct Node的别名,可有可无用于简化命名
typedef Node* LinkList;///LinkList是Node*的别称
void initList(LinkList *head)///初始化链表:接受一个指向链表头指针的指针
{///动态内存分配
    if ((*head = (LinkList)malloc(sizeof(Node))) == NULL)
        exit(-1);///内存分配失败,函数终止程序
    (*head)->next = NULL; ///初始化头节点:指针域赋空,数据域不设置
}
void creatList(LinkList head)///在只有头节点的情况下,定义并创建一个新的结点指针,通过输入不断壮大原只有头节点的列表
{
    LinkList p, tail = head; ///tail被初始化为头节点,p
    int count;
    scanf("%d", &count);
    while (count > 0)
    {
        p = (LinkList)malloc(sizeof(Node));///将malloc返回的void*类型的指针 转换为LinkList类型
       if(p==NULL)exit(-1);
        scanf("%d%d", &p->coefficient, &p->exponent);
        tail->next = p; ///插入节点p至tail后面
        tail = p;       ///更新tail:向后移动,便于下一次插入
        count--;
    }
    tail->next = NULL;///循环结束,最后一个节点设置为NULL,表示链表的结束
}
void printList(LinkList head)
{    if(head==NULL)exit(-1); ///exit()函数:立即终止程序的运行,返回状态值(0表示成功,非0表示异常)
    LinkList p = head->next; ///初始化指针p,指向链表第一个实际的数据点
    while (p)///p==NULL标志着链表到达结尾
    {
        if (p == head->next) ///检查p是否仍指向第一个数据节点
            printf("%d %d", p->coefficient, p->exponent);
        else                ///不是第一个元素,打印的时候前面加一个空格
            printf(" %d %d", p->coefficient, p->exponent);
        p = p->next;        ///节点的移动
    }
}

///已完成链表的创建初始化,读入节点数据信息,设置输出格式的操作


void multiplication(LinkList list1, LinkList list2)
{
    LinkList result, p = list1->next, q , tail, newNode;
    initList(&result);///初始化链表(使存在)
    tail = result;   ///指向头节点
    while (p)///直接调用判断是否为空,所以初始化为链表的第一个有效节点
    {///关键点:在循环外初始化p,循环内初始化q,使p节点不变,遍历q链表的每一个节点
     ///难点:指数保持递减,合并同类项  
        q = list2->next;///第一个有效节点
        while (q)///遍历
        {
            // 创建“新建的”newNode存储p,q组合后得到的新节点
            newNode = (LinkList)malloc(sizeof(Node));
            newNode->coefficient = p->coefficient * q->coefficient;///运算法则
            newNode->exponent = p->exponent + q->exponent;
            newNode->next = NULL; ///封底

            LinkList temp = result;    ///在result链表中查找应该插入newNode的位置
            while (temp->next && newNode->exponent < temp->next->exponent)
            {///temp下一个节点非空(temmp不是链表的最后一个元素)、temp第一个"有效元素"大于插入节点,后移遍历
                temp = temp->next;///后移
            }
            // 插入或者合并同类项
            if (temp->next == NULL || newNode->exponent > temp->next->exponent)///可以直接将新节点插入的两条件:1.已经遍历完,插到尾部。2.插入节点大于temp中的被遍历到的节点,可以直接插入
            {   ///链表插入节点,从后往前避免信息更换错乱
                newNode->next = temp->next;
                temp->next = newNode;
            }
            else if (newNode->exponent == temp->next->exponent)
            {   ///合并同类项
                temp->next->coefficient += newNode->coefficient;
                // 如果合并同类项后系数为0,得删除这个节点
                if(temp->next->coefficient==0)
                {///删除节点
                    LinkList deleteNode=temp->next; ///使删除的节点还可以被找回(保存指针)
                    temp->next=deleteNode->next; ///删除节点的方法:我的后面=我后面的后面
                 free(deleteNode); ///节点被移除后释放内存(不能再被找回)
                }
                free(newNode);  ///删除节点并释放内存(该节点信息已经被合并利用,节点不需要了)
            }
            q = q->next;///下一个
        }
        p = p->next;///下一个
    }
    if (result->next==NULL)///结果链表为空(全都抵消)
    {
        free(result);  ///释放头节点内存
        printf("0 0");
    }
    else  ///链表不为空,打印结果链表
    {
        printList(result);
    }
}


void addition(LinkList list1, LinkList list2)///旨在两个链表的相加,并打印出结果
{///newNode作为临时变量,是每次迭代中 独立的、新分配的节点,是用于构建链表的一个个独立的节点(再次调用mallloc分配新内存)
    LinkList result, p = list1->next, q = list2->next, tail, newNode; ///result(相加后的链表),p,q(分别跳过头节点,指向两链表的有效节点),tail(追踪至链表的尾部),newNode(临时存储新创建的节点)
    initList(&result);        ///初始化链表(分配内存,设置头节点,数据域为空)
    tail = result;            /// 设置为头节点,便于后续添加新节点(移动)
    while (p && q)            ///两个链表有一个遍历完,就结束
    {
        newNode = (LinkList)malloc(sizeof(Node));

        // 当p的指数大于q的指数,将节点p复制给newNode,将newNode移动到result的末尾,p往后移动,q不动
        if (p->exponent > q->exponent)///两链表内指数是递减顺序输入的,输出顺序也是指数递减
        {
            newNode->coefficient = p->coefficient;
            newNode->exponent = p->exponent;
            newNode->next = NULL;   ///将该链表封底,
            tail->next = newNode;  ///将得到的结果项 连接到result后面
            tail = newNode;        ///更新指针(后移)
            p = p->next;  ///p指数大,直接存p该项,p往下遍历,下一项再与q该项比较
        }
        else if (p->exponent < q->exponent)
        {
            // 当p的指数小于q的指数,将节点q复制给newNode,将newNode移动到result的末尾,q往后移动,p不动
            newNode->coefficient = q->coefficient;
            newNode->exponent = q->exponent;
            newNode->next = NULL;
            tail->next = newNode;
            tail = newNode;
            q = q->next;
        }
        else  // 指数相等,系数相加。如果相加后的系数为0,则将p,q直接移动到下一位
   
        {
             if (p->coefficient + q->coefficient == 0)
            {
                p = p->next;   ///相同指数,系数互为相反数,相加后该项消失,两链表直接后移
                q = q->next;
                free(newNode);  ///newNode没有被链接到结果链表,则释放分配给他的内存
            }
            else
            {
                newNode->coefficient = p->coefficient + q->coefficient;
                newNode->exponent = p->exponent;
                newNode->next = NULL;
                tail->next = newNode;
                tail = newNode;
                p = p->next;    ///两链表都后移
                q = q->next;
            }
        }
    }
    // 如果p或q还有剩余节点,直接接到result的末尾
    if (p==NULL)
    {
        tail->next = q;
    }
    if (q==NULL)
    {
        tail->next = p;
    }

    if (result->next==NULL)///两链表相加后各项系数都为0,只包含头节点,没有有效节点
    {
        free(result);  ///释放内存(有malloc就要有free)
        printf("0 0");
    }
    else    ///相加结束后,result链表有有效节点,打印
    {
        printList(result);
    }
}

int main()
{
    LinkList list1, list2;
    initList(&list1);   ///初始化两个链表(加取地址符,可更改源文件的内容)
    initList(&list2);
    creatList(list1);   ///创建两个信息读入完整的链表
    creatList(list2);
    multiplication(list1, list2);  ///一元多项式的乘法
    printf("\n");  
    addition(list1, list2);        ///一元多项式的加法
    return 0;
}



​

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值