链表实现多项式的加法(C语言)

1、创建结点类型

用链表存储一个多项式,那么该链表的每一个结点就代表多项式的某一项。所以我们的每一个结点必须包含三个信息:多项式的系数、多项式的指数以及指向下一个结点的指针。

typedef int data_t;//指数、系数类型

typedef struct node {
        data_t xishu;//系数
        data_t zhishu;//指数
        struct node *next;//用于存放下一个结点的地址
}node_t;

2、初始化链表

链表初始化,实质是实现头结点的创建和初始化设置。

node_t * CreateLinkList(void)
{
        node_t *head;
        /* 动态开辟头结点存储空间 */
        head = malloc(sizeof(node_t));  
        if(head == NULL)
                return NULL;
    
        memset(head,0,sizeof(node_t));    /* 将头结点空间数据清零 */
        head->next = NULL;    /* 头结点next域没有指向表示为空链表 */
    
        return head;    
}

3、打印多项式

传入一个指向多项式链表的指针p,遍历该链表依次打印链表内容。(一次打印一个结点)

需将第一项拿出来单独打印,因为我们不希望第一项系数的正号被打印出来,然后还要考虑到指数为0,只有常数的情况

void DisplayLinkList(node_t *head)
{
        node_t *p = head->next;
        if(p != NULL)
        {
                if(p->zhishu == 0) //打印第一项
                {
                        printf("%d",p->xishu);
                        p = p->next;

                }
                else
                {
                        printf("%dx^%d",p->xishu,p->zhishu);
                        p = p->next;
                }
        }

        while(p != NULL)  //遍历后面的结点
        {
                if(p->zhishu == 0)
                {
                        printf("+%d",p->xishu);
                        p = p->next;
                }

                else
                {
                        if(p->xishu < 0)
                        {
                                printf("%dx^%d",p->xishu,p->zhishu);
                                p = p->next;
                        }
                        else
                        {
                                printf("+%dx^%d",p->xishu,p->zhishu);
                                p = p->next;
                        }
                }
        }
        printf("\n");
}

4、插入结点

本文的输入主要采用的是插入结点,从第0个结点开始,后面两个参数为系数和指数

如果想从键盘输入或者输入完整多项式,只需要在main函数改动即可

int InsertLinkList(node_t *head,int local,data_t myxishu,data_t myzhishu)
{
        int i;
        node_t *p = head;
        node_t *q;

        /* 判断链表是否存在 */
        if(head == NULL)
                return -1;

	 /* 找到需要插入结点的前一个结点p */
        for(i=0;i<local;i++)
        {
                p = p->next;
                if(p == NULL)
                        return -1;
        }


    /* 创建需要插入结点q,并初始化数据 */
        q = malloc(sizeof(node_t));
        if(q == NULL)
                return -1;
        q->xishu = myxishu;
        q->zhishu = myzhishu;


	  /* p结点插入结点q */
        q->next = p->next;
        p->next = q;

        return 0;
}

5 、排序

输入的多项式可能并不是有序的,这时我们需要将多项式按指数降序排列(或按指数升序排列),以简化后续多项式的相加操作,这里我们选用插入排序算法。

void SortLinkList(node_t *head)
{
        node_t *p;
        node_t *q;
        node_t *r;

        if(head == NULL)
                return ;
        if(head->next == NULL)
                return ;

        p = head->next->next;/* 从链表第1个结点开始遍历 */
        head->next->next = NULL;

        while(p != NULL)
        {
                q = p;
                p = p->next;

    /* 顺序链表中找到需要插入结点的前一个结点 */
                r = head;
                while(r->next != NULL)
                {
                if(r->next->zhishu < q->zhishu)
                        break;
                        r = r->next;
                }
            /* 在结点r后插入结点q */
                q->next = r->next;
                r->next = q;
        }

}

6 、合并多项式

从两个待相加的多项式的表头开始,比较两个结点的指数大小,若相同,则将两个结点的系数相加得到新的系数,申请一个新结点(结点的系数为新得到的系数,指数与这两个结点的指数相同)尾插到新链表的后面即可。若两个结点的指数不相同,则申请一个新结点(新结点的系数和指数与两个结点中指数较大的结点相同)尾插到新链表后面即可

node_t *ConnectLinkList(node_t **head1,node_t **head2)
{
        node_t *r;
        node_t *t;
    /* 选择head1作为新链表的头结点 */
        node_t *p = (*head1)->next;
        (*head1)->next = NULL;

        node_t *q = (*head2)->next;
        free(*head2);
        *head2 = NULL;

        t = *head1;
        while(p != NULL && q != NULL)
        {
                if(p->zhishu > q->zhishu)
                {
                        r = p;
                        p = p->next;
                }
                else if(p->zhishu < q->zhishu)
                {
                        r = q;
                        q = q->next;
                }
                else
                {
    /* 将指数相同的两个结点系数相加,系数存储到其中一共结点中,而另外一个结点释放 */
                        r = p;
                        p = p->next;
                        r->xishu += q->xishu;
                        node_t *f = q;
                        q = q->next;
                        free(f);
                }
            /* 结点t后插入结点r */
                r->next = NULL;
                t->next = r;
                t = r;
        }
	    /* 余下结点的处理 */
        if(p == NULL)
        {
                t->next = q;
        }
        else
        {
                t->next = p;
        }
        return *head1;
}

7、完整代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


typedef int data_t;//指数、系数类型

typedef struct node {
        data_t xishu;//系数
        data_t zhishu;//指数
        struct node *next;//用于存放下一个结点的地址
}node_t;


node_t * CreateLinkList(void)
{
        node_t *head;
        /* 动态开辟头结点存储空间 */
        head = malloc(sizeof(node_t));  
        if(head == NULL)
                return NULL;
    
        memset(head,0,sizeof(node_t));    /* 将头结点空间数据清零 */
        head->next = NULL;    /* 头结点next域没有指向表示为空链表 */
    
        return head;    
}





void DisplayLinkList(node_t *head)
{
        node_t *p = head->next;
        if(p != NULL)
        {
                if(p->zhishu == 0) //打印第一项
                {
                        printf("%d",p->xishu);
                        p = p->next;

                }
                else
                {
                        printf("%dx^%d",p->xishu,p->zhishu);
                        p = p->next;
                }
        }

        while(p != NULL)  //遍历后面的结点
        {
                if(p->zhishu == 0)
                {
                        printf("+%d",p->xishu);
                        p = p->next;
                }

                else
                {
                        if(p->xishu < 0)
                        {
                                printf("%dx^%d",p->xishu,p->zhishu);
                                p = p->next;
                        }
                        else
                        {
                                printf("+%dx^%d",p->xishu,p->zhishu);
                                p = p->next;
                        }
                }
        }
        printf("\n");
}


int InsertLinkList(node_t *head,int local,data_t myxishu,data_t myzhishu)
{
        int i;
        node_t *p = head;
        node_t *q;

        /* 判断链表是否存在 */
        if(head == NULL)
                return -1;

	 /* 找到需要插入结点的前一个结点p */
        for(i=0;i<local;i++)
        {
                p = p->next;
                if(p == NULL)
                        return -1;
        }


    /* 创建需要插入结点q,并初始化数据 */
        q = malloc(sizeof(node_t));
        if(q == NULL)
                return -1;
        q->xishu = myxishu;
        q->zhishu = myzhishu;


	  /* p结点插入结点q */
        q->next = p->next;
        p->next = q;

        return 0;
}


void SortLinkList(node_t *head)
{
        node_t *p;
        node_t *q;
        node_t *r;

        if(head == NULL)
                return ;
        if(head->next == NULL)
                return ;

        p = head->next->next;/* 从链表第1个结点开始遍历 */
        head->next->next = NULL;

        while(p != NULL)
        {
                q = p;
                p = p->next;

    /* 顺序链表中找到需要插入结点的前一个结点 */
                r = head;
                while(r->next != NULL)
                {
                if(r->next->zhishu < q->zhishu)
                        break;
                        r = r->next;
                }
            /* 在结点r后插入结点q */
                q->next = r->next;
                r->next = q;
        }
}


node_t *ConnectLinkList(node_t **head1,node_t **head2)
{
        node_t *r;
        node_t *t;
    /* 选择head1作为新链表的头结点 */
        node_t *p = (*head1)->next;
        (*head1)->next = NULL;

        node_t *q = (*head2)->next;
        free(*head2);
        *head2 = NULL;

        t = *head1;
        while(p != NULL && q != NULL)
        {
                if(p->zhishu > q->zhishu)
                {
                        r = p;
                        p = p->next;
                }
                else if(p->zhishu < q->zhishu)
                {
                        r = q;
                        q = q->next;
                }
                else
                {
    /* 将指数相同的两个结点系数相加,系数存储到其中一共结点中,而另外一个结点释放 */
                        r = p;
                        p = p->next;
                        r->xishu += q->xishu;
                        node_t *f = q;
                        q = q->next;
                        free(f);
                }
            /* 结点t后插入结点r */
                r->next = NULL;
                t->next = r;
                t = r;
        }
	    /* 余下结点的处理 */
        if(p == NULL)
        {
                t->next = q;
        }
        else
        {
                t->next = p;
        }
        return *head1;
}


int main()
{    
        data_t myxishu;
        data_t myzhishu;
        node_t *head1;
        node_t *head2;
        head1 = CreateLinkList();
        InsertLinkList(head1,0,3,0);
        InsertLinkList(head1,1,2,2);
        InsertLinkList(head1,2,4,5);
        InsertLinkList(head1,3,6,4);
        DisplayLinkList(head1);
        SortLinkList(head1);

        head2 = CreateLinkList();
        InsertLinkList(head2,0,5,5);
        InsertLinkList(head2,1,4,0);
        InsertLinkList(head2,2,-2,7);
        InsertLinkList(head2,3,4,3);
        DisplayLinkList(head2);
        SortLinkList(head2);

        head1 = ConnectLinkList(&head1,&head2);
        DisplayLinkList(head1);
}

8、运行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值