C语言中的合并双链表

C语言中的合并双链表,c,merge,C,Merge,用C语言合并两个链表 我尝试合并两个排序的双链接列表。当我用不同的输入运行代码时,有时代码会因为EXC_BAD_访问错误而崩溃。我不明白为什么,代码对我来说似乎很完美,我用类似的方法合并了两个单链表,它成功了。 有人能解释一下吗?谢谢 #include <stdio.h> #include <stdlib.h> typedef struct Node { struct Node* prior; struct Node*

用C语言合并两个链表

我尝试合并两个排序的双链接列表。当我用不同的输入运行代码时,有时代码会因为EXC_BAD_访问错误而崩溃。我不明白为什么,代码对我来说似乎很完美,我用类似的方法合并了两个单链表,它成功了。 有人能解释一下吗?谢谢

   #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;
}
#包括
#包括
定义表结点
{
结构节点*prior;
结构节点*下一步;
int值;
}节点,*列表;
列表创建_列表()
{          
列表头=(列表)malloc(sizeof(节点));
如果(!head)退出(-1);
列表尾;
尾=头;
printf(“请输入双链接列表的长度:\n”);
内伦;
scanf(“%d”和“len”);
对于(int i=0;ivalue=val;
尾部->下一步=新建;
新->先前=尾部;
尾巴=新的;
}
回流头;
}
列表合并列表(列表a、列表b)
{
如果(a==NULL | | b==NULL)退出(-1);
list p=(list)malloc(sizeof(Node));
列表l=p;
while(a&b)
{
如果(a->valuevalue)
{
p->next=a;
a->prior=p;
p=a;
a=a->next;
}
其他的
{
p->next=b;
b->prior=p;
p=b;
b=b->next;
}
}
如果(a!=NULL)
{
p->next=a;
a->prior=p;
}
如果(b!=NULL)
{
p->next=b;
b->prior=p;
}
返回l;
}
int main(){
列表l=创建_列表();
l=l->next;
列表m=创建_列表();
m=m->next;
列表n=合并列表(l,m);
n=n->next;
while(n)
{
printf(“%d\n”,n->value);
n=n->next;
}
返回0;
}

问题在于,在
创建\u列表
中,您没有使用
NULL
初始化
new->next

从这个错误来看,在
merge_list
中将指针与
NULL
进行比较是没有意义的,
new->next
的答案已经解决了最重要的错误(即没有初始化
new->next

但是,代码中还有其他错误,a)导致内存泄漏,b)导致链表不正确

main
中,您有:

 list l = create_list();
 l=l->next;  // Why ......
你为什么要这样“扔掉”第一个元素?那是内存泄漏!此外,它还意味着
l->prio
不是应该的空值

我知道这是因为你的
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;
}

正确格式化代码。修正缩进,不要每隔一行换行。请修改间距和缩进。您有多个用于插入节点的代码副本。将其移动到一个函数中,以节省错误搜索工作并提高可读性。我为您做了标记修正中不明显的部分。请执行下一步,删除空行,应用一致的缩进(包括删除引线空白,这可能是我介绍的)。好的,代码现在可以工作了。但是我很困惑。新建->下一步=NULL之间的区别是什么;什么也不做?那么为什么我成功地创建了这两个列表呢?@Liu malloc'ed内存未初始化,所以您需要自己进行所有初始化。如果您什么也不做,那么
new->next
(或者在最后
tail->next
)可以保存任何值。那不是你想要的!对于链接列表,您总是希望
tail->next
NULL@Liu您只是没有正确构造列表。您需要以某种方式保留有关列表长度的信息。因为您没有显式地保留元素的数量,所以您需要以某种方式指示列表的结束位置——要么使用空指针,要么使用sentinel元素(表示结束的单例)。如果使用calloc而不是malloc,则不需要使用NULL初始化
new->next
,因为calloc会执行此任务。那么,如果只调用create_list function(),为什么可以打印链接列表呢?在单链表中,我仍然没有声明new->next=NULL,代码仍然有效,为什么?酷!但我还没有找出最重要的错误!你能再给我解释一下吗?@Liu我不知道你的意思。。。最重要的错误是您从未这样做过:
new->next=NULL但不是尾部->下一步=新建;足够地为什么我的代码在没有new->next=NULL的单链表中工作;?谢谢大家!@刘否,
tail->next=new
您需要初始化
new->next
我还有一个问题,我需要释放在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;
}