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