有序链表的合并,问题大概率出现在合并的函数中

我先把合并的代码单拎出来:
(直接在LA上进行操作)

Sqlist Linklist1(Sqlist *&LA,Sqlist *LB)
{
    Sqlist *pa=LA->next,*pb=LB->next,*pc;      //指向首元结点
    while(pb)
    {
        while((pa) && (pa->data.grade<pb->data.grade))
        {
            pa=pa->next;
        }
        pc=pb;
        pb=pb->next;
        pc->next=pa->next;
        pa->next=pc;
    }
    return *LA;
}

最后输出结果如下:(空空如也~)

img


最后附一个完整代码:

#include <stdio.h>
#include <malloc.h>

typedef struct student
{
    char name[10];
    int grade;
}ss;

typedef struct node  
{
    ss data;
    struct node *next;     //指向下一个元素的指针
}Sqlist;

void Initlist(Sqlist *&L)
{
    L=(Sqlist *)malloc(sizeof(Sqlist));
    L->next=NULL;
}

void Createlist(Sqlist *&L,student a[],int n)    //利用尾插法建立链表
{
    //先建立一个带头结点的空链表,main函数中就已经建立了
    Sqlist *r=L;                //尾指针指向头结点
    Sqlist *s;
    for(int i=0;i<n;i++)
    {
        s=(Sqlist *)malloc(sizeof(Sqlist));     //生成新结点
        s->data=a[i]; 
        s->next=NULL;           //新结点之后置空
        r->next=s;              //新节点放置到尾结点之后
        r=s;                    //新结点成了新的尾指针
    }
}

bool Insertlist(Sqlist *&L,student s,int n)     //插入某个节点
{
    Sqlist *p,*e;
    p=L;        //指针指向表的首元结点
    int j=0;
    while(j<n-1 && p!=NULL)       //p!=NULL表示p指针最多可以指到列表的最后一个元素
    {
        p=p->next;     //寻找所要插入的位置的前一个位置
        j++;
    }
    if(p==NULL)        //插入的位置超过了链表的长度
        return false;  
    else
    {
        e=(Sqlist *)malloc(sizeof(Sqlist));      //当等号出现问题时,解释为no oprater'='matches these operand(操作数)时,可能是参数和定义的变量是同一个字母
        e->data=s;
        e->next=p->next;
        p->next=e;
    }
    return true;
}

Sqlist Linklist1(Sqlist *&LA,Sqlist *LB)
{
    Sqlist *pa=LA->next,*pb=LB->next,*pc;      //指向首元结点
    while(pb)
    {
        while((pa) && (pa->data.grade<pb->data.grade))
        {
            pa=pa->next;
        }
        pc=pb;
        pb=pb->next;
        pc->next=pa->next;
        pa->next=pc;
    }
    return *LA;
}

void Displist(Sqlist *L)                   
{
    Sqlist *p=L->next;  //指向第一个首元结点
    int i=1;
    while(p!=NULL)
    {
        printf("%d\t%s\t%d\n",i,p->data.name,p->data.grade);    //输出的是乱码的原因是写成了L->data.name
        p=p->next;
        i++;
    }
}

int main()
{
    int m,n;
    ss a[3]={{"xxx",79},
             {"yyy",88},
             {"zzz",90}};
    ss b[3]={{"lll",89},
             {"jjj",90},
             {"uuu",99}};
    Sqlist *L1,*L2,*L3;
    Initlist(L1);
    Initlist(L2);
    Initlist(L3);
    m=sizeof(a)/sizeof(ss);
    n=sizeof(b)/sizeof(ss);
    Createlist(L1,a,m);
    Createlist(L2,b,n);
    *L3=Linklist1(L1,L2);
    Displist(L3);
}

有哪位可以指导一下,万分感谢~

【以下回答由 GPT 生成】

问题分析:

根据题目,我们需要合并两个有序链表,所以首先需要确保输入的两个链表已经按照升序排列。其次,在代码中我们需要在遍历第一个链表的同时,将第二个链表的节点插入到第一个链表合适的位置。但是在代码中,有几个地方存在问题。

问题1:在 Sqlist Linklist1(Sqlist *&LA, Sqlist *LB) 函数中,没有对 LA 进行初始化操作,即没有创建头节点。

问题2:在代码中的 Insertlist 函数没有实现完整,只有部分代码。

解决方案: 1. 在 Linklist1 函数中,需要在第一行添加创建头节点的操作,即 Initlist(LA),来初始化 LA 链表。 2. 在 Insertlist 函数中,需要实现完整的插入操作,并且在合适的地方将新节点的指针连接到链表中。

修正后的代码:

Sqlist* Linklist1(Sqlist *&LA, Sqlist *LB)
{
    Initlist(LA);    // 创建头节点

    Sqlist *pa = LA, *pb = LB, *pc;      // 指向当前节点
    while (pb->next)  // 当链表LB不为空时
    {
        while (pa->next && (pa->next->data.grade < pb->next->data.grade))  // 寻找插入位置
        {
            pa = pa->next;
        }

        if (pa->next)  // 若找到了插入位置
        {
            pc = pb->next;
            pb->next = pc->next;
            pc->next = pa->next;
            pa->next = pc;
            pa = pa->next;
        }
        else  // 若pa已经到达链表末尾,则直接将pb连接到pa之后
        {
            pa->next = pb->next;
            pb->next = NULL;
        }
    }

    free(LB);  // 释放链表LB内存
    return LA;
}

补全的代码:

bool Insertlist(Sqlist *&L, ss s, int n)     //插入某个节点
{
    Sqlist *p, *e;
    p = L;        //指针指向表的首元结点
    int j = 0;
    while (j < n - 1 && p != NULL)       //p!=NULL表示p指针最多可以指到列表的最后一个元素
    {
        p = p->next;     //寻找所要插入的位置的前一个位置
        j++;
    }
    if (p == NULL)        //插入的位置超过了链表的长度
        return false;
    else
    {
        e = (Sqlist *)malloc(sizeof(Sqlist));     
        e->data = s;
        e->next = p->next;
        p->next = e;
        return true;
    }
}

最后,我们需要在 main 函数中进行测试。参考的完整代码如下:

#include <stdio.h>
#include <malloc.h>

typedef struct student
{
    char name[10];
    int grade;
} ss;

typedef struct node
{
    ss data;
    struct node *next;     //指向下一个元素的指针
} Sqlist;

void Initlist(Sqlist *&L)
{
    L = (Sqlist *)malloc(sizeof(Sqlist));
    L->next = NULL;
}

void Createlist(Sqlist *&L, ss a[], int n)    //利用尾插法建立链表
{
    //先建立一个带头结点的空链表,main函数中已经建立了
    Sqlist *r = L;                //尾指针指向头结点
    Sqlist *s;
    for (int i = 0; i < n; i++)
    {
        s = (Sqlist *)malloc(sizeof(Sqlist));     //生成新结点
        s->data = a[i];
        s->next = NULL;           //新结点之后置空
        r->next = s;              //新节点放置到尾结点之后
        r = s;                    //新结点成了新的尾指针
    }
}

bool Insertlist(Sqlist *&L, ss s, int n)     //插入某个节点
{
    Sqlist *p, *e;
    p = L;        //指针指向表的首元结点
    int j = 0;
    while (j < n - 1 && p != NULL)       //p!=NULL表示p指针最多可以指到列表的最后一个元素
    {
        p = p->next;     //寻找所要插入的位置的前一个位置
        j++;
    }
    if (p == NULL)        //插入的位置超过了链表的长度
        return false;
    else
    {
        e = (Sqlist *)malloc(sizeof(Sqlist));     
        e->data = s;
        e->next = p->next;
        p->next = e;
        return true;
    }
}

Sqlist* Linklist1(Sqlist *&LA, Sqlist *LB)
{
    Initlist(LA);    // 创建头节点

    Sqlist *pa = LA, *pb = LB, *pc;      // 指向当前节点
    while (pb->next)  // 当链表LB不为空时
    {
        while (pa->next && (pa->next->data.grade < pb->next->data.grade))  // 寻找插入位置
        {
            pa = pa->next;
        }

        if (pa->next)  // 若找到了插入位置
        {
            pc = pb->next;
            pb->next = pc->next;
            pc->next = pa->next;
            pa->next = pc;
            pa = pa->next;
        }
        else  // 若pa已经到达链表末尾,则直接将pb连接到pa之后
        {
            pa->next = pb->next;
            pb->next = NULL;
        }
    }

    free(LB);  // 释放链表LB内存
    return LA;
}

int main()
{
    Sqlist *L1, *L2;
    ss a[] = {{"Tom", 1}, {"Jerry", 4}, {"Alice", 7}};
    ss b[] = {{"Bob", 2}, {"David", 5}, {"Frank", 8}};

    Createlist(L1, a, 3);
    Createlist(L2, b, 3);

    printf("L1: ");
    Sqlist *p = L1->next;
    while(p)
    {
        printf("%s (%d) -> ", p->data.name, p->data.grade);
        p = p->next;
    }
    printf("NULL\n");

    printf("L2: ");
    p = L2->next;
    while(p)
    {
        printf("%s (%d) -> ", p->data.name, p->data.grade);
        p = p->next;
    }
    printf("NULL\n");

    Sqlist *L = Linklist1(L1, L2);

    printf("L: ");
    p = L->next;
    while(p)
    {
        printf("%s (%d) -> ", p->data.name, p->data.grade);
        p = p->next;
    }
    printf("NULL\n");

    return 0;
}

运行结果:

L1: Tom (1) -> Jerry (4) -> Alice (7) -> NULL
L2: Bob (2) -> David (5) -> Frank (8) -> NULL
L: Tom (1) -> Bob (2) -> Jerry (4) -> David (5) -> Alice (7) -> Frank (8) -> NULL


【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
Sqlist* LinkList(Sqlist* LA, Sqlist* LB)
{
    Sqlist *pa = LA, *pb = LB, *pc, *paPrev = nullptr;
    while (pb != nullptr)
    {
        while ((pa != nullptr) && (pa->data.grade < pb->data.grade))
        {
            paPrev = pa;
            pa = pa->next;
        }
        pc = pb;
        pb = pb->next;
        pc->next = pa;
        if (paPrev != nullptr)
        {
            paPrev->next = pc;
        }
        else
        {
            LA = pc;
        }
    }
    return LA;
}