一个c程序,用于添加两个长度不等的单链表,在其所有节点中包含一个数字

一个c程序,用于添加两个长度不等的单链表,在其所有节点中包含一个数字,c,data-structures,C,Data Structures,这是我面试时问的问题。我得到了两个长度不等的链表,每个节点上都有一个数字。我被要求建立一个第三个链表,其中包含两个链表的总和,同样以节点中1位数字的形式。 前任: 链表1是 4-7-9-6 链表2是 5-7 那么第三个链表就是 4-8-5-3 有人能给我推荐一个高效的算法,在空间复杂度方面最小的妥协吗 颠倒列表1和2 逐元素求和(而 保持携带),将 结果将显示一个列表3,您可以 从头到尾构造 或 将列表1和2转换为整数(例如,int list1AsInt=0;对于每个节点{list1AsInt*

这是我面试时问的问题。我得到了两个长度不等的链表,每个节点上都有一个数字。我被要求建立一个第三个链表,其中包含两个链表的总和,同样以节点中1位数字的形式。 前任: 链表1是 4-7-9-6 链表2是 5-7 那么第三个链表就是 4-8-5-3 有人能给我推荐一个高效的算法,在空间复杂度方面最小的妥协吗

  • 颠倒列表1和2
  • 逐元素求和(而 保持携带),将 结果将显示一个列表3,您可以 从头到尾构造
  • 将列表1和2转换为整数(例如,
    int list1AsInt=0;对于每个节点{list1AsInt*=10;list1AsInt+=此节点的值;}
  • 把这些整数加起来
  • 将结果转换为链接列表(例如,
    valueOfBrandNewNode=list3AsInt%10;list3AsInt/=10;添加指向上一个节点的新节点;
  • 遍历两个列表一次,以了解 他们的长度。比如说,, 让我们假设列表1更长 由N个节点组成
  • 创建一个列表3来表示总和 没有携带和列表4到 代表进位
  • 对于列表1的前N个节点, 将这些值复制到列表3并使 列表4的值应为0
  • 对于列表1的其余节点 和2,逐元素求和, 将mod 10之和放入列表3,然后 进货清单4。通过 列表4是否全部为0的布尔值
  • 将值为0的最后一个节点添加到列表中 四,
  • 如果列表4完全为0,则完成。 否则,返回到步骤2, 将清单3视为 新的列表1和列表4作为新的 清单2。我们知道这条河的长度 新列表1是长度中较大的一个 旧列表1和2的长度 新名单中的第二条比这多了一条
  • 将两个列表中的每个数字作为其ASCII等价物读入索引为0的字符数组
  • 在两个字符数组上使用
    atoi()
    函数(如果担心长度,可以使用
    atol()
    atol()
  • 两个数字相加
  • 使用
    itoa()
    函数将其转换为字符数组,然后放回新列表

  • 尽管如此,我承认
    itoa()
    函数不是标准函数。

    如果列表是双重链接的,那么很容易:

  • 将两个列表遍历到底
  • 在相应节点中添加数字,并保留进位数字
  • 在列表3中创建节点
  • 将一个节点移到列表的开头,然后重复

  • 如果列表按相反顺序存储数字,解决方案可能会简单得多

    然而,在给定的约束条件下,这里有一种方法

  • 查找两个列表的数字,从
    n=0开始
  • 创建一个带有数字总和的
    节点
  • 更新(正在运行的)
    进位
  • 结果
    列表的
    头部插入新创建的节点
  • 以下是(未测试的)C代码

    typedef struct DigitNode\u{
    整数位数;
    结构DigitNode_*next;
    }数字节点;
    /*返回SLL末尾的第n个元素;
    如果不存在这样的元素,则返回NULL。
    见:https://stackoverflow.com/questions/2598348/
    */
    外部DigitNode*nthNodeFromTail(DigitNode*listHead,大小\u t n);
    /*将pNode推到前面,即作为列表的新标题*/
    外部无效推前(DigitNode**plisHead,DigitNode*pNode);
    /*将新列表创建为a和b的总和,并返回新列表的标题。
    a->4->7->9->6->NULL
    b->5->7->NULL
    导致
    c->4->8->5->3->空
    */
    DigitNode*SumDigitList(DigitNode*a、DigitNode*b){
    数字节点*c=0;
    整数进位=0;
    /*i是从列表尾部向后的节点位置*/
    对于(尺寸i=0;/*请参见*/;i++中的“断开”){
    const DigitNode*const ithNodeA=nthNodeFromTail(a,i);
    const DigitNode*const ithNodeB=nthNodeFromTail(b,i);
    /*当两个列表的处理完成时停止*/
    如果(!ithNodeA&!ithNodeB){
    打破
    }
    常量int ithDigitA=ithNodeA?ithNodeA->数字:0;
    常量int-ithDigitB=ithNodeB?ithNodeB->数字:0;
    
    assert((0查看以下代码:

    node *add_two_linkedlist(node *head1,node *head2)
    {
        int i,j,temp;
        node *p,*n;
        p=head1;
        n=head2;
        i=count(head1);
        j=count(head2);
    
        if(i>j)
        {
            while(j!=0)
            {
                p->data=p->data+n->data;
                if(p->data>10)
                {
                    temp=(p->data)/10;
                    p->data=(p->data)%10;
                    p=p->next;
                    n=n->next;
                    p=p->data+temp;
                    j--;
                }               
            }   
            return head1;
        }
    
        if(j>i)
        {
            while(i!=0)
            {
                n->data=p->data+n->data;
                if(n->data>10)
                {
                    temp=(n->data)/10;
                    n->data=(n->data)%10;
                    n=n->next;
                    p=p->next;
                    n=n->data+temp;
                    i--;
                }               
            }   
            return head2;
        }
    }
    

    这很简单。假设最左边的节点是最高有效位。对齐两个列表,添加并传播进位。返回后,如果需要,创建一个新节点

    #include <stdio.h>
    
    
    struct list {
     int val;
     struct list * next;
    };
    
    
        int listadd (struct list  *l1, struct list *l2) {
    
            if ((l1 == NULL) || (l2 == NULL))
                    return;
            int carry = 0;
    
            if ((l1->next == NULL) && (l2->next != NULL)) {
                    carry += listadd (l1, l2->next) + l2->val;
                    return carry;
            }
    
            else if ((l1->next != NULL) && (l2->next == NULL)) {
                    carry +=listadd (l1->next, l2);
                    l1->val = l1->val + carry;
            }
            else if ((l1->next != NULL) && (l2->next != NULL)) {
                    carry += listadd (l1->next, l2->next);
            }
            else if ((l1->next == NULL) && (l2->next == NULL)) {
                    l1->val = l1->val + l2->val;
                    carry = l1->val/10;
                    l1->val = l1->val%10;
                    return carry;
            }
    
            carry = l1->val/10;
            l1->val = l1->val%10;
            return carry;
    }
    
    struct list * createnode (int val) {
      struct list * temp = (struct list *) malloc (sizeof(struct list));
      temp->val = val;
      temp->next = NULL;
      return temp;
    }
    
    int main() {
       int carry = 0;
       struct list *l1 = createnode(1);
    l1->next = createnode(2);
    
       struct list *l2 = createnode(7);
       l2->next = createnode(8);
    
      carry = listadd(l1,l2);
    
      if (carry != 0) {
            struct list * temp = createnode(carry);
            temp->next = l1;
            l1 = temp;
      }
    
    
       while (l1!= NULL) {
            printf ("%d", l1->val);
            l1=l1->next;
       }
    }
    
    #包括
    结构列表{
    int-val;
    结构列表*下一步;
    };
    int listadd(结构列表*l1,结构列表*l2){
    if((l1==NULL)| |(l2==NULL))
    返回;
    整数进位=0;
    如果((l1->next==NULL)和&(l2->next!=NULL)){
    进位+=列表添加(l1,l2->next)+l2->val;
    返运;
    }
    else如果((l1->next!=NULL)和&(l2->next==NULL)){
    进位+=列表添加(l1->next,l2);
    l1->val=l1->val+进位;
    }
    else如果((l1->next!=NULL)和&(l2->next!=NULL)){
    进位+=列表添加(l1->next,l2->next);
    }
    else如果((l1->next==NULL)和&(l2->next==NULL)){
    l1->val=l1->val+l2->val;
    进位=l1->val/10;
    l1->val=l1->val%10;
    返运;
    }
    进位=l1->val/10;
    l1->val=l1->val%10;
    返运;
    }
    结构列表*创建节点(int val){
    结构列表*临时=(结构列表*)malloc(sizeof(结构列表));
    温度->瓦尔=瓦尔;
    temp->next=NULL;
    返回温度;
    }
    int main(){
    整数进位=0;
    结构列表*l1=createnode(1);
    l1->next=createnode(2);
    结构列表*
    
    #include <stdio.h>
    
    
    struct list {
     int val;
     struct list * next;
    };
    
    
        int listadd (struct list  *l1, struct list *l2) {
    
            if ((l1 == NULL) || (l2 == NULL))
                    return;
            int carry = 0;
    
            if ((l1->next == NULL) && (l2->next != NULL)) {
                    carry += listadd (l1, l2->next) + l2->val;
                    return carry;
            }
    
            else if ((l1->next != NULL) && (l2->next == NULL)) {
                    carry +=listadd (l1->next, l2);
                    l1->val = l1->val + carry;
            }
            else if ((l1->next != NULL) && (l2->next != NULL)) {
                    carry += listadd (l1->next, l2->next);
            }
            else if ((l1->next == NULL) && (l2->next == NULL)) {
                    l1->val = l1->val + l2->val;
                    carry = l1->val/10;
                    l1->val = l1->val%10;
                    return carry;
            }
    
            carry = l1->val/10;
            l1->val = l1->val%10;
            return carry;
    }
    
    struct list * createnode (int val) {
      struct list * temp = (struct list *) malloc (sizeof(struct list));
      temp->val = val;
      temp->next = NULL;
      return temp;
    }
    
    int main() {
       int carry = 0;
       struct list *l1 = createnode(1);
    l1->next = createnode(2);
    
       struct list *l2 = createnode(7);
       l2->next = createnode(8);
    
      carry = listadd(l1,l2);
    
      if (carry != 0) {
            struct list * temp = createnode(carry);
            temp->next = l1;
            l1 = temp;
      }
    
    
       while (l1!= NULL) {
            printf ("%d", l1->val);
            l1=l1->next;
       }
    }