首页 文章

节点的链接列表插入什么都不显示

提问于
浏览
1
#include<stdio.h>
#include<stdlib.h>

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

void insert( struct node *q,int num)
{
    struct node *temp;

    if( q == NULL)
    {
        q = (struct node*)malloc(sizeof(struct node));
        q->data = num;
        q->next = NULL;
    }
    else
    {
        temp = q;
        while( temp != NULL)
        {
            temp = temp->next;
        }
        temp = (struct node*)malloc(sizeof(struct node));
        temp->data = num;
        temp->next = NULL;
    }
}

void display(struct node *q)
{
    struct node *temp;
    temp = q;
    while(temp != NULL)
    {
        printf("%d",temp->data);
        temp = temp->next;
    }
}



int main()
{
    struct node *a;
    a = NULL;
    insert( a,13);
    insert( a,13);
    display(a);
    return 0;
}

insert 函数中, q 是指向struct node的指针,该节点初始化为NULL .

如果q为NULL,我在这里看到1st . 如果它为null,那么我正在分配堆内存,数据和下一个指针,这样q现在是一个取消引用第一个数据的指针 . 如果q不是NULL,那么我接受一个临时指针指向一个由q指向的结构节点,所以直到temp变为NULL temp转到temp-> next,然后它分配堆内存,将数据和下一个指针放到空值 .

但它没有显示我的显示功能,请在此更正我,以及如何在链表中使用堆栈和堆内存 .

8 回答

  • 0

    更改

    insert( struct node *q,int num)insert( struct node **q,int num)

    并在 main() 内,改变

    insert( a,13)insert( &a,13)

    你需要修改实际参数而不是形式参数,所以使用 pass by address 而不是 pass by value
    意味着,在 insert() 内,当您为 q 分配值时,它没有被反映到 a ,因为您只是传递了一个's value, in order to make the change reflected to a pass a'的地址 .

    也,
    one more problem 位于 insert()else 块内
    while( temp != NULL) 更改为 while( temp->next != NULL)

  • 0

    这是您的程序的固定版本 . 问题是指针被复制到函数 by value 中,所以当你的函数退出时,在这种情况下传入 a 的指针不会被分配给任何东西 . 你唯一要做的就是泄露内存,通过分配一些而不是 free 来实现它 .

    解决方案是传递指针 by reference ,并在C中完成指针到指针 .

    #include<stdio.h>
    #include<stdlib.h>
    
    struct node
    {
        int data;
        struct node *next;
    };
    
    void insert( struct node **q,int num)
    {
        struct node *temp;
    
        if( *q == NULL)
        {
            *q = (struct node*)malloc(sizeof(struct node));
            (*q)->data = num;
            (*q)->next = NULL;
        }
        else
        {
            temp = *q;
            while( temp != NULL)
            {
                temp = temp->next;
            }
            temp = (struct node*)malloc(sizeof(struct node));
            temp->data = num;
            temp->next = NULL;
        }
    }
    
    void display( struct node *q)
    {
        struct node *temp;
        temp = q;
        while(temp != NULL)
        {
    
            printf("%d",temp->data);
            temp = temp->next;
        }
    }
    
    
    
    int main()
    {
        struct node *a;
        a = NULL;
        insert( &a,13);
        insert( &a,13);
        display(a);
        free(a->next); //de-alloc memory
        free(a);
        return 0;
    }
    
  • 3

    您需要返回在insert中分配的指针 .

    在main中,a是指向NULL的指针 . 在第一次插入之后,a仍然是指向NULL的指针,因为q具有指针,而不是a .

    a的值是您可以找到结构节点的地址 . q是a的值的副本,因此是NULL . 当你malloc()时,它为q赋值,这是一个struct节点的地址,但它没有改变!

    或者:

    /* a has a value and it doesn't malloc q */
    main() {
       struct node a = {0};
    
       insert(&a, 13);
    }
    

    要么

    /* you return the value of q (address of struct node) and assign it to a */
    struct node *insert(struct node *q, int num) {
       blah blah
    
       return q;
    }
    
    main() {
       struct node *a = NULL;
    
       a = insert(a, 13);
    }
    

    要么

    /* I'm finding this hard to explain because of 2 redirections */
    void insert( struct node **q, int num ) {
    
       if ( *q == NULL ) {
       *q = malloc() etc etc
       }
    }
    
    main() {
       struct node *a = NULL;
    
       insert(&a, 13);
    }
    

    但是你在插入的后半部分也犯了类似的错误 . 您需要分配内存并将其分配给下一个,而不是相反 .

  • 1

    回想一下,在C参数中是 pass-by-value ,包括指针参数 .

    q == NULL 时,你正在分配内存并将该内存分配给 q ,但是这个 won't 更改 q 在你的函数之外:只更改函数内的 q 的副本 .

    为了更改 q 指向的参数,并将这些更改反映在函数之外,您需要将指针传递给指针,例如:

    void insert(struct node **q, int num)
    

    并改变您使用 q 的方式,例如

    if (*q == NULL)
        *q = (struct node *) malloc(sizeof(struct node));
    

    此外,在你的情况下,你应该循环到 temp->next == NULL ,然后添加你的新节点:

    temp->next = (struct node*) malloc(sizeof(struct node));
    
  • 1

    将此代码替换为您的代码:

    while( temp != NULL)
        {
            temp = temp->next;
        }
        temp = (struct node*)malloc(sizeof(struct node));
        temp->data = num;
        temp->next = NULL;
    

    通过

    while( temp->next != NULL)
        {
            temp = temp->next;
        }
        temp->next = (struct node*)malloc(sizeof(struct node));
        temp->next->data = num;
        temp->next->next = NULL;
    
  • 0

    有两种方法可以解决这个问题 .

    • 在函数中传递q的地址 .

    • 将返回类型从void更改为node . 每次插入新节点后返回根节点(此方法很简单但不可取) .

  • 0

    看起来问题是你迭代列表的末尾 . 所以,当temp变为null时,你说,嘿,我已经找到了结局 . 然后你创建一个新节点 . 但是,您永远不会将上一个节点指向新节点 .

    我会改变这个:

    while( temp != NULL)
    

    对此:

    while( temp->next != NULL)
    

    因此,当您到达目的地时,您仍会参考您的列表 . 然后,您需要相应地更改其余逻辑,但至少可以实现 .

    正如其他人所说,您的功能也不适用于初始节点 . 我会考虑使用一个单独的函数来初始化一个空列表 . 但这主要是一种风格选择 .

  • 1

    您必须在 insert() 函数中使用指向指针的指针,因为您使用 malloc() 分配新内存,但指针仍将指向NULL . 因此,要修改指针本身,如果使用参数进行操作,则必须使用指向指针的指针 . 恕我直言,如果你返回指针会好得多 .

相关问题