合并C语言中的双链表

时间:2019-01-22 14:45:10

标签: c merge

使用C语言合并两个链接列表。

我试图合并两个排序的双链表。当我使用不同的输入运行代码时,有时代码会因EXC_BAD_ACCESS错误而崩溃。我不知道为什么,代码对我来说似乎很完美,并且我使用类似的方式合并了两个单个链表,它确实有效。    有人可以解释吗?谢谢!

   #include <stdio.h>  

   #include <stdlib.h>

   typedef struct Node
   {

    struct Node* prior;

    struct Node* next;

    int value;

   }Node,*list;

  list create_list()
  {          

      list head = (list)malloc(sizeof(Node));

      if(!head) exit(-1);

      list tail;

      tail=head;

      printf("Please enter the length of double linked list:\n");

      int len;

      scanf("%d",&len);

       for(int i=0;i<len;i++)

        {

         list new = (list)malloc(sizeof(Node));

         printf("Please enter the value of node:\n");

         int val;

         scanf("%d",&val);

         new->value=val;

         tail->next = new;

         new->prior=tail;

         tail=new;
    }
    return head;
  }

   list merge_list(list a, list b)
   {

      if(a==NULL||b==NULL) exit(-1);

      list p=(list)malloc(sizeof(Node));

      list l=p;

      while(a&&b)
      {

         if(a->value<=b->value)
          {

            p->next = a;

            a->prior=p;

            p=a;

            a=a->next;

           }
      else
      {

           p->next = b;

          b->prior=p;

          p=b;

          b=b->next;

      }
    }
   if(a!=NULL)

     {

        p->next=a;

        a->prior=p;
    }

    if(b!=NULL)
    {

      p->next=b;

      b->prior=p;

     }

    return l;
}

    int main() {

     list l = create_list();

     l=l->next;

     list m = create_list();

     m=m->next;

    list n =merge_list(l,m);

     n=n->next;

    while(n)
   {

       printf("%d\n",n->value);

       n=n->next;
   }

     return 0;
}

2 个答案:

答案 0 :(得分:1)

问题在于,在create_list中,您没有使用new->next初始化NULL

由于该错误,在merge_list中将指针与NULL进行比较是没有意义的。

答案 1 :(得分:0)

@alinsoar的答案已经解决了最重要的错误(即new->next没有初始化)。

但是,您的代码中还有其他错误,这些错误可能导致a)内存泄漏,b)链表错误。

main中,您拥有:

 list l = create_list();
 l=l->next;  // Why ......

您为什么要“扔掉”像这样的第一个元素?那是内存泄漏!此外,这意味着l->prio并非应为NULL!

我知道这是因为您的create_list在开头插入了一个虚假节点。但是,不要仅仅通过扔掉节点来修复它。修复功能。

执行以下操作:

list create_list()
{          
  list head = NULL; // Do not use malloc here - just assign NULL
  list tail = NULL;

  printf("Please enter the length of double linked list:\n");
  int len;
  scanf("%d",&len);

  for(int i=0;i<len;i++)
  {
     list new = malloc(sizeof(Node));  // do not cast malloc
     new->next = NULL;                 // set the next pointer

     printf("Please enter the value of node:\n");
     int val;
     scanf("%d",&val);
     new->value=val;

     // Add the node to the end
     new->prior=tail;
     if (tail)
     {
         tail->next = new;
     }
     else
     {
         // First element so update head
         head = new;
     }
     tail=new;
  }
  return head;
}

使用此代码,您一开始就没有多余的元素,可以删除main中的代码l=l->next;。类似的更改适用于merge_list,但我将作为练习留给您。

最后,您的main应该是:

int main() {
    list l = create_list();
    list m = create_list();
    list n =merge_list(l,m);
    while(n) {
        printf("%d\n",n->value);
        n=n->next;
    }
    return 0;
}