c语言链表插入节点问题

为何这样写插入节点会失败?

img


第一张图片可以正常插入

img


第二张图片显示插入失败了

下面是源代码

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

typedef struct xxx
{
    char name[10];
    float price;
}ZCD;

//节点
typedef struct yyy
{
    ZCD zcd;//数据域
    struct xxx* next;//地址域
}note;

//输出
void printfs(note*p)
{
    note* i = NULL;
    for (i = p;i != NULL;i = i->next)
    {
        printf("%s的价格为%.2f元\n", i->zcd.name,i->zcd.price);
    }
}

//释放
void frees(note* p)
{
    note* i = NULL;
    note* temp = NULL;
    for (i = p;i != NULL;)
    {
        temp = i->next;
        free(i);
        i = temp;
    }
}

//插入节点
note* insert(note* p, int n,note*q)
{
    note* temp = p;
    if (n == 0)
    {
        q->next = p;
        p = q;
    }
    /*for (int i = 0;i < n;i++)
    {
        temp = temp->next;
    }
    q->next = temp;
    temp = q;*///不等价
    for (int i = 0;i < n-1;i++)
    {
        temp = temp->next;
    }
    q->next = temp->next;
    temp->next = q;
    return p;
}

void main(void)
{
    /*char a[5] = { 0 };
    printf("请输入一段字符:");
    gets(a);
    char* p = (char*)calloc(5, 1);
    if (p == NULL)
    {
        printf("开辟空间失败");
    }
    strcpy(p,a);
    puts(p);
    free(p);*/
    //动态申请节点空间
    note* p1 = (note*)malloc(sizeof(note));
    note* p2 = (note*)malloc(sizeof(note));
    note* p3 = (note*)malloc(sizeof(note));
    if (p1 == NULL || p2 == NULL || p3 == NULL)
    {
        printf("空间申请失败!\n");
        return -1;
    }
    printf("空间申请成功!\n");

    //对每个数据域进行赋值
    strcpy(p1->zcd.name, "包子");
    p1->zcd.price = 1.5;
    strcpy(p2->zcd.name, "豆浆");
    p2->zcd.price = 2.0;
    strcpy(p3->zcd.name, "油条");
    p3->zcd.price = 0.5;

    //对每个地址域进行赋值(单向非循环)
    p1->next = p2;
    p2->next = p3;
    p3->next = NULL;
    printfs(p1);
    //开辟新节点空间
    note* p4 = (note*)malloc(sizeof(note));
    if (p4 == NULL)
    {
        printf("空间申请失败!\n");
        return -1;
    }
    printf("空间申请成功!\n");
    strcpy(p4->zcd.name, "胡辣汤");
    p4->zcd.price = 2.5;
    //确定插入位置
    int n;
    printf("请输入插入的位置:");
    scanf_s("%d",&n);
    //插入新节点
    note* lala = insert(p1, n, p4);
    printfs(lala);
    //释放所有节点
    frees(lala);
}

主要问题出在

for (int i = 0;i < n;i++)
    {
        temp = temp->next;
    }
    q->next = temp;
    temp = q;

有问过别人,他说temp->next代表的是上一个节点的地址域,temp代表的是下一个节点的地址,两者不等价
我不理解的是为什么temp跟temp->next的数据类型明明相同,为什么代表的含义缺不同呢,是跟“->”的定义有关吗

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

前面的代码也不对,应该 p->next = null;而不是 p = q;
只是因为是结尾,错误没有暴露出来
下面,temp已经指向最后节点了
还有,你也没考虑传入的n比现有的链表长度大怎么办

for (int i = 0;i < n && temp -> next != null i++)

这里要双重判断

代码里几处错误,见注释修改处,供参考:

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

typedef struct xxx
{
    char name[10];
    float price;
}ZCD;

//节点
typedef struct yyy
{
    ZCD zcd;//数据域
    struct yyy* next;//struct xxx* next;// 修改
}note;

//输出
void printfs(note*p)
{
    note* i = NULL;
    for (i = p; i != NULL; i = i->next)
    {
        printf("%s的价格为%.2f元\n", i->zcd.name,i->zcd.price);
    }
}
 
//释放
void frees(note* p)
{
    note* i = NULL;
    note* temp = NULL;
    for (i = p;i != NULL;)
    {
        temp = i->next;
        free(i);
        i = temp;
    }
}
 
//插入节点
note* insert(note* p, int n, note* q)
{
    note* temp = p;
    if (n == 0)
    {
        q->next = p;
        p = q;
    }
    /*for (int i = 0;i < n;i++)
    {
        temp = temp->next;
    }
    q->next = temp;
    temp = q;*///不等价
    else{           // 修改 
        for (int i = 1;temp && i < n;i++)  // 修改 for (int i = 0;i < n-1;i++)
        {
            temp = temp->next;
        }
        if (temp){                     // 修改
            q->next = temp->next;
            temp->next = q;
        }                              // 修改
    }
    return p;
}
 
void main(void)
{
    /*char a[5] = { 0 };
    printf("请输入一段字符:");
    gets(a);
    char* p = (char*)calloc(5, 1);
    if (p == NULL)
    {
        printf("开辟空间失败");
    }
    strcpy(p,a);
    puts(p);
    free(p);*/
    //动态申请节点空间
    note* p1 = (note*)malloc(sizeof(note));
    note* p2 = (note*)malloc(sizeof(note));
    note* p3 = (note*)malloc(sizeof(note));
    if (p1 == NULL || p2 == NULL || p3 == NULL)
    {
        printf("空间申请失败!\n");
        return;  // -1;                修改
    }
    printf("空间申请成功!\n");
 
    //对每个数据域进行赋值
    strcpy(p1->zcd.name, "包子");
    p1->zcd.price = 1.5;
    strcpy(p2->zcd.name, "豆浆");
    p2->zcd.price = 2.0;
    strcpy(p3->zcd.name, "油条");
    p3->zcd.price = 0.5;
 
    //对每个地址域进行赋值(单向非循环)
    p1->next = p2;
    p2->next = p3;
    p3->next = NULL;
    printfs(p1);
    //开辟新节点空间
    note* p4 = (note*)malloc(sizeof(note));
    if (p4 == NULL)
    {
        printf("空间申请失败!\n");
        return;  //-1;                修改
    }
    printf("空间申请成功!\n");
    strcpy(p4->zcd.name, "胡辣汤");
    p4->zcd.price = 2.5;
    //确定插入位置
    int n;
    printf("请输入插入的位置:");
    scanf("%d",&n);
    //插入新节点
    note* lala = insert(p1, n, p4);
    printfs(lala);
    //释放所有节点
    frees(lala);
}