如何在C语言中合并两个链表

如何在C语言中合并两个链表,c,linked-list,singly-linked-list,C,Linked List,Singly Linked List,在C语言中,我得到了两个已排序的链表,我正在尝试将它们合并在一起,以便它们按排序顺序排列。有人能告诉我为什么我的代码不起作用吗 struct ListNode { int val; struct ListNode *next; }; struct ListNode *mergeTwoLists(struct ListNode *l1, struct ListNode *l2) { struct ListNode *node; node = NULL;

在C语言中,我得到了两个已排序的链表,我正在尝试将它们合并在一起,以便它们按排序顺序排列。有人能告诉我为什么我的代码不起作用吗

struct ListNode {
    int val;
    struct ListNode *next;
};

struct ListNode *mergeTwoLists(struct ListNode *l1, struct ListNode *l2) {

    struct ListNode *node;

    node = NULL;

    struct ListNode *n = (struct ListNode *)malloc(sizeof(struct ListNode));

    node = n;

    while (l1 != NULL && l2 != NULL) {
        if ((*l1).val < (*l2).val) {
            (*n).val = (*l1).val;
            l1 = (*l1).next;
        } else {
            (*n).val = (*l2).val;
            l2 = (*l2).next;
        }
        (*n).next = (struct ListNode *)malloc(sizeof(struct ListNode));
        n = (*n).next;
    }
    if (l1 != NULL) {
        n = l1;
    }
    if (l2 != NULL) {
        n = l2;
    }
    return node;
}
struct ListNode{
int-val;
结构ListNode*next;
};
结构ListNode*MergeTwoList(结构ListNode*l1,结构ListNode*l2){
结构ListNode*节点;
node=NULL;
结构ListNode*n=(结构ListNode*)malloc(sizeof(结构ListNode));
节点=n;
while(l1!=NULL&&l2!=NULL){
如果((*l1.val<(*l2.val){
(*n).val=(*l1).val;
l1=(*l1)。下一步;
}否则{
(*n.val=(*l2.val);
l2=(*l2)。下一步;
}
(*n).next=(struct ListNode*)malloc(sizeof(struct ListNode));
n=(*n)。下一步;
}
如果(l1!=NULL){
n=l1;
}
如果(l2!=NULL){
n=l2;
}
返回节点;
}
  • 首先,决定是合并原始列表,还是返回列表的副本(但具有相同的值)
  • 如果您想要一个副本,那么对于您传递的每个输入节点,应该有一个确切的
    malloc()
    。(您可以验证在合并循环中,
    l1
    l2
    是高级的,并且(可能)分配了一个节点)

#包括
结构节点{
结构节点*下一步;
int-val;
};
#如果你想克隆
#包括
结构节点*克隆(结构节点*p)
{
结构节点*q;
如果(!p)返回NULL;
q=malloc(sizeof*q);
*q=*p;
返回q;
}
#定义克隆(x)克隆(x)
#否则
#定义克隆(x)(x)
#恩迪夫
结构节点*合并(结构节点*l1,结构节点*l2)
{
结构节点伪={NULL,0},*此处;
对于(此处=&dummy;l1 | | l2;此处=此处->下一步){
如果(!l2 | | l1&&l1->val){
此处->下一步=克隆(l1);l1=l1->下一步;
}
如果(!l1 | | l2){
这里->下一步=克隆(l2);l2=l2->下一步;
}
}
返回dummy.next;
}
/*一些测试数据*/
结构节点evens[]={
{evens+1,0},{evens+2,2},{evens+3,4},{evens+4,6},{NULL,8},};
结构节点赔率[]={
{赔率+1,1},{赔率+2,3},{赔率+3,5},{赔率+4,7},{赔率+5,9},{NULL,11},};
无效打印(结构节点*p)
{
对于(;p;p=p->next){
printf(“%d”,p->val);
}
printf(“\n”);
}
内部主(空)
{
结构节点*两者;
printf(“赔率”);print(赔率);
printf(“evens:);print(evens);
两者=合并(赔率,均等);
printf(“两者”);print(两者);
printf(“赔率”);print(赔率);
printf(“evens:);print(evens);
返回0;
}

您只需创建一个新列表,按递增顺序从两个列表中复制值,而不是合并这两个列表,但如果列表已用尽,则无法在其中一个列表中复制其余元素

请注意以下额外备注:

  • 您可能需要将列表合并到位,并返回指向合并列表头部的指针
  • 语法
    (*l1).val
    在C中并不完全错误,但是指针语法
    l1->val
    被认为更可读
以下是修改后的版本:

struct ListNode{
int-val;
结构ListNode*next;
};
结构ListNode*MergeTwoList(结构ListNode*l1,结构ListNode*l2){
结构ListNode*head,*n;
n=头=空;
while(l1!=NULL&&l2!=NULL){
如果(l1->val){
如果(n==NULL){
n=水头=l1;
}否则{
n=n->next=l1;
}
l1=l1->next;
}否则{
如果(n==NULL){
n=水头=l2;
}否则{
n=n->next=l2;
}
l2=l2->next;
}
}                
如果(l1!=NULL){
如果(n==NULL){
水头=l1;
}否则{
n->next=l1;
}
}否则{
如果(n==NULL){
头部=l2;
}否则{
n->next=l2;
}
}
回流头;
}

您没有显示任何测试数据,但是当一个列表用尽时,您的逻辑是不完整的:它只适用于剩余源列表中的一个附加元素。您需要在此处使用循环。如果要压缩原始的两个列表,则不需要
malloc()
。顺便说一句:请不要写
(*foo).bar而不是
foo->bar
。这两种形式都是100%等效的,但没有人使用第一种形式。如果合并两个列表,通常会得到一个由原来两个列表的节点组成的新列表,并且不需要分配任何额外的内存,只需重新连接指针即可。但是,您可以复制前两个列表中的每个节点,并将这些副本放在一个排序的列表中——但完成后,您仍然负责释放所有三个列表中的节点。在这两个选项中,您试图实现哪一个?请提供。
#include <stdio.h>

struct node {
        struct node *next;
        int val;
        };

#if WANT_CLONE
#include <stdlib.h>
struct node *clone(struct node *p)
{
struct node *q;
if (!p) return NULL;
q = malloc (sizeof *q);
*q = *p;
return q;
}

#define CLONE(x) clone(x)
#else
#define CLONE(x) (x)
#endif

struct node *merge(struct node *l1, struct node *l2)
{
struct node dummy = {NULL,0}, *here;

for(here = &dummy; l1 || l2; here = here->next) {
        if (!l2 || l1 && l1->val <= l2->val) {
                here->next= CLONE(l1); l1 = l1->next;
                }
        else    if(!l1 || l2) {
                here->next= CLONE(l2); l2 = l2->next;
                }
        }

return dummy.next;
}

        /* Some test data */
struct node evens[] = {
{evens+1, 0}, {evens+2, 2}, {evens+3, 4}, {evens+4, 6}, {NULL, 8}, };

struct node odds[] = {
{odds+1, 1}, {odds+2, 3}, {odds+3, 5}, {odds+4, 7}, {odds+5, 9}, {NULL, 11}, };

void print(struct node *p)
{
for( ; p; p = p->next) {
        printf(" %d", p->val);
        }
printf("\n");
}

int main(void)
{
struct node *both;

printf("odds:"); print(odds);
printf("evens:"); print(evens);
both = merge(odds, evens);
printf("both:"); print(both);

printf("odds:"); print(odds);
printf("evens:"); print(evens);

return 0;
}