c语言单向链表复制的问题

创建了一个长度为5的单向链表A并录入了数据,现要利用该链表A复制一个一样的链表B,但新链表B只能输出前两个数据

#include
#include
typedef struct node
{
    int val;
    struct node *next;
}*linklist;
int main()
{
    linklist head,p,last;
    head=NULL;int num;
    for(int i=0;i<5;i++)
    {    scanf("%d",&num);
        p=(linklist)malloc(sizeof(struct node));
        p->val=num;
        if(head==NULL)
        {
            head=p;
            last=head;
        }
        else
        {
            last->next=p;
            last=p;
            last->next=NULL;
        }
    }//**A链表的创建**
    linklist nhead,nlast,np;
    nhead=NULL;int t=0;
    while(head)
    {    
        
        np=(linklist)malloc(sizeof(struct node));
        if(t==0)
        {
            nhead=head;
            nlast=nhead;
        }
        else
        {
            np=head;
            nlast->next=np;
            nlast=np;
            nlast->next=NULL;
        }
        head=head->next;
        t++;
    }//复制B链表
    while(nhead)
    {
        printf("%d ",nhead->val);
        nhead=nhead->next;
    }//打印B链表的结果
}

![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/961049939086191.png "#left")
上图为运行结果


题目要求复制一个一样的链表B,但只输出前两个数据,所以在复制链表B时需要记录复制的节点数,当复制的节点数达到2时就停止复制。

#include<stdio.h>
#include<stdlib.h>

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

int main() {
    linklist head,p,last;
    head=NULL;
    int num;
    for(int i=0;i<5;i++) {
        scanf("%d",&num);
        p=(linklist)malloc(sizeof(struct node));
        p->val=num;
        if(head==NULL) {
            head=p;
            last=head;
        } else {
            last->next=p;
            last=p;
            last->next=NULL;
        }
    }//**A链表的创建**

    linklist nhead=NULL,nlast=NULL,np;
    int t=0;
    while(head && t<2) { // 只复制前两个节点
        np=(linklist)malloc(sizeof(struct node));
        np->val = head->val;
        if(t==0) {
            nhead=np;
            nlast=nhead;
        } else {
            nlast->next=np;
            nlast=np;
            nlast->next=NULL;
        }
        head=head->next;
        t++;
    }//复制B链表

    while(nhead) {
        printf("%d ",nhead->val);
        nhead=nhead->next;
    }//打印B链表的结果
    return 0;
}

以下内容部分参考ChatGPT模型:


你好,关于复制单向链表的问题,你可以采用遍历原链表A的方式,每遍历一个节点就新建一个节点插入到链表B的末尾。具体实现可以参考下面的代码:

#include <stdio.h>
#include <stdlib.h>

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

// 创建链表A
linklist createListA() {
    linklist head = NULL, last = NULL, p;
    int num;
    for (int i = 0; i < 5; i++) {
        scanf("%d", &num);
        p = (linklist)malloc(sizeof(struct node));
        p->val = num;
        p->next = NULL;
        if (head == NULL) {
            head = p;
            last = head;
        } else {
            last->next = p;
            last = p;
        }
    }
    return head;
}

// 复制链表B
linklist copyListB(linklist headA) {
    linklist headB = NULL, lastB = NULL, p;
    while (headA && headB == NULL) { // 复制前两个节点
        p = (linklist)malloc(sizeof(struct node));
        p->val = headA->val;
        p->next = NULL;
        if (headB == NULL) {
            headB = p;
            lastB = headB;
        } else {
            lastB->next = p;
            lastB = p;
        }
        headA = headA->next;
    }
    while (headA) { // 复制剩余节点
        p = (linklist)malloc(sizeof(struct node));
        p->val = headA->val;
        p->next = NULL;
        lastB->next = p;
        lastB = p;
        headA = headA->next;
    }
    return headB;
}

// 输出链表
void printList(linklist head) {
    while (head) {
        printf("%d ", head->val);
        head = head->next;
    }
    printf("\n");
}

int main() {
    linklist headA = createListA();
    linklist headB = copyListB(headA);
    printf("链表A:");
    printList(headA);
    printf("链表B:");
    printList(headB);
    return 0;
}

这里采用了两个函数,createListA()用于创建链表A,copyListB()用于复制链表B。其中,在复制链表B时,我们先复制前两个节点,然后再复制剩余节点。最后,printList()函数用于输出链表的值。

输出结果如下:

1 2 3 4 5
链表A:1 2 3 4 5
链表B:1 2 3 4 5

如果我的建议对您有帮助、请点击采纳、祝您生活愉快

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7520914
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:【一元多项式算法】设一个一元多项式采用带头结点的单链表存储,所有结点 按照升幂方式链接。设计一个算法,求两个多项式 A 和 B 的乘积,结果多项式 C 存放在新辟的空间中。
  • 除此之外, 这篇博客: C语言程序设计第五版谭浩强课后答案 第九章习题答案中的 11.有两个链表a和b,设结点中包含学号、姓名。从a链表中删去与b链表中有相同学号的那些结点。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 解题思路及答案:

    对于b链表中的每一个节点,都从a链表的表头开始查找,如果可以找到,直接删除,如果找不到,继续从a链表表头找下一个b的节点。

    #include <stdio.h>
    typedef struct student
    {
    	int num;
    	double grade;
    	struct student *next;
    } student;
    student *del(student *a, student *b)
    {
    	student *pre, *current, *head;
    	head = a;
    
    	while (b != NULL)
    	{
    		//重置指针指向a链表的头部
    		pre = head;
    		current = head->next;
    		//a 链表的头等于b
    		if (pre->num == b->num)
    		{
    			pre->next = NULL;
    			pre = current;
    			current = current->next;
    			//更新表头
    			head = pre;
    		}
    		else
    		{
    			while (pre->next != NULL)
    			{
    				if (current->num == b->num)
    				{
    					//找到就删除
    					pre->next = current->next;
    					break;
    				}
    				else
    				{
    					//否则继续遍历
    					pre = pre->next;
    					current = current->next;
    				}
    			}
    		}
    		b = b->next;
    	}
    	return head;
    }
    
    void printList(student *root)
    {
    	printf("----\n");
    	int i = 0;
    	while (root != NULL)
    	{
    		printf("student %d -> %d -> %.2lf\n", i, root->num, root->grade);
    		root = root->next;
    		i++;
    	}
    }
    
    int main()
    {
    	student a[3] = { { 1, 79 }, { 4, 36 }, { 5, 79 } };
    	for (int i = 0; i < 2; i++)
    	{
    		a[i].next = &a[i + 1];
    	}
    	a[2].next = NULL;
    	printf("链表a:\n");
    	printList(&a[0]);
    
    	student b[2] = { { 5, 38 }, { 4, 98 } };
    	for (int i = 0; i < 1; i++)
    	{
    		b[i].next = &b[i + 1];
    	}
    	b[1].next = NULL;
    	printf("链表b:\n");
    	printList(&b[0]);
    	student *combine = del(a, b);
    	printf("删除之后:\n");
    	while (combine != NULL)
    	{
    		printf("%d -> %.2lf\n", combine->num, combine->grade);
    		combine = combine->next;
    	}
    
    	return 0;
    }
    

    运行截图:
    谭浩强课后习题答案

找到输出错误的原因了:line36中把head的值给了nhead,则两个链表的头指针指向相同,

while(head)
{    
    
    np=(linklist)malloc(sizeof(struct node));
    np->val=head->val;
    if(nhead==NULL)
    {
        nhead=np;
        nlast=nhead;
    }
    else
    {
    
        nlast->next=np;
        nlast=np;
        nlast->next=NULL;
    }
    head=head->next;
    
}

这就对了。(line47中t++删去,判断条件改为nhead==NULL,这样更加流利)
不过为什么只输出前两项还没想明白