链表中的数字相加----链表专题

链表中的数字相加

在这里插入图片描述
在这里插入图片描述

分析:
这是一个看起来还蛮简单的题目,很多初步学习算法的同学的第一反应是根据链表求出整数,然后直接将两个整数相加,最后把结果用链表表示。但是这种思路最大的问题是没有考虑到整数有可能会溢出,当链表较长时,表示的整数很大,可能会超过int甚至是long的范围,如果根据链表求出整数就有可能会溢出

通常,两个整数相加都是先加个数,再加十位数,然后依次相加更高位数字。由于题目中的整数使用单向链表表示,因此先将两个尾节点相加,再将两个整数的倒数第二个节点相加,并依次对前面的节点相加。
但是两个尾节点相加之后,在单向链表中就无法前进到倒数第二个节点。在单向链表中只能从前面的节点朝着next指针方向前进到后面的节点,却无法从后面的节点前进到前面的节点。

解决这个问题的办法就是把表示整数的链表反转,反转之后的链表的头节点表示个位数,尾节点表示最高位数,此时从两个链表的头结点开始相加,就相当于从整数的个位数开始相加。

做加法还需要要特别注意的是进位。如果两个整数的个位数相加和超过或者等于10,就会往十位数产生一个进位。在下一步做十位数相加时就要把这个进位考虑进去。

总体思路如下:
在这里插入图片描述

做加法:
在这里插入图片描述

最后将得到的结果再次反转:
在这里插入图片描述
最后贴代码:
在这里插入图片描述

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head1 ListNode类 
     * @param head2 ListNode类 
     * @return ListNode类
     */
    //链表反转函数
    public ListNode reverselist(ListNode head)
    {
        ListNode pre=null;
        ListNode cur=head;
        while(cur!=null)
        {
            ListNode next=cur.next;
            cur.next=pre;
            pre=cur;
            cur=next;
        }
        return pre;
    }
    public ListNode addInList (ListNode head1, ListNode head2) {
        ListNode dummy = new ListNode(0);//哨兵结点
        ListNode summy=dummy;
        //反转链表
        head1=reverselist(head1);
        head2=reverselist(head2);
        //进位计数器
        int carry=0;
        while(head1!=null||head2!=null)
        {
            int sum=(head1==null?0:head1.val)+(head2==null?0:head2.val)+carry;
            carry=sum>=10?1:0;
            sum=sum>=10?sum-10:sum;
            ListNode newnode=new ListNode(sum);
            summy.next=newnode;
            summy=newnode;
            head1=head1==null?null:head1.next;
            head2=head2==null?null:head2.next;
        }
        if(carry>0)
        {
            summy.next=new ListNode(carry);
        }
        return reverselist(dummy.next);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
具体步骤如下: 1. 定义一个结构体来存储一个多项式的每一项。 ``` struct node{ float coef; // 系数 int expn; // 指数 struct node *next; // 指向下一个节点的指针 }; ``` 2. 定义一个函数来创建一个多项式。该函数将一个字符串作为输入,将其转换为一个多项式存储在链表。 ``` struct node* create(char* str){ struct node *head, *p, *q; head = (struct node*)malloc(sizeof(struct node)); // 分配头节点的空间 head->coef = 0; head->expn = 0; head->next = NULL; p = head; while(*str){ q = (struct node*)malloc(sizeof(struct node)); // 分配新节点的空间 q->coef = atof(str); while(*str != ' ') str++; // 跳过系数部分 q->expn = atoi(++str); while(*str != ' ' && *str) str++; // 跳过指数部分 p->next = q; p = q; } p->next = NULL; return head; } ``` 3. 定义一个函数来打印一个多项式。 ``` void print(struct node* head){ struct node *p = head->next; while(p){ printf("%.2fx^%d ", p->coef, p->expn); p = p->next; } printf("\n"); } ``` 4. 定义一个函数来将两个多项式相加。该函数接收两个链表指针,返回一个链表指针。 ``` struct node* add(struct node* head1, struct node* head2){ struct node *p = head1->next, *q = head2->next, *r, *s; struct node *head = (struct node*)malloc(sizeof(struct node)); head->coef = 0; head->expn = 0; head->next = NULL; s = head; while(p && q){ r = (struct node*)malloc(sizeof(struct node)); if(p->expn < q->expn){ r->coef = p->coef; r->expn = p->expn; p = p->next; } else if(p->expn > q->expn){ r->coef = q->coef; r->expn = q->expn; q = q->next; } else{ r->coef = p->coef + q->coef; r->expn = p->expn; p = p->next; q = q->next; } s->next = r; s = r; } while(p){ r = (struct node*)malloc(sizeof(struct node)); r->coef = p->coef; r->expn = p->expn; p = p->next; s->next = r; s = r; } while(q){ r = (struct node*)malloc(sizeof(struct node)); r->coef = q->coef; r->expn = q->expn; q = q->next; s->next = r; s = r; } s->next = NULL; return head; } ``` 5. 测试函数。 ``` int main(){ struct node *head1, *head2, *head3; char str1[50], str2[50]; printf("请输入第一个多项式:"); fgets(str1, 50, stdin); printf("请输入第二个多项式:"); fgets(str2, 50, stdin); head1 = create(str1); head2 = create(str2); head3 = add(head1, head2); printf("第一个多项式:"); print(head1); printf("第二个多项式:"); print(head2); printf("相加结果:"); print(head3); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值