【问题标题】:How to store the data dynamically in linked list in C?如何将数据动态存储在C中的链表中?
【发布时间】:2021-11-08 05:14:16
【问题描述】:

我正在尝试将值动态存储在链表中。

我希望用户输入链接列表的大小。然后根据我要分配内存的输入(即如果 Input : 3 那么应该创建三个节点)。

如果为节点分配内存,那么我将head 节点存储在temp 中。

之后我想将数据存储在列表中,直到列表结束

我使用的算法如下

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

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


// Printing the list
void printList(struct node *ptr)
{
    int i = 1;
    while(ptr != NULL)
    {
        printf("\n Value in Node %d : %d",i ,ptr->data);
        ptr = ptr->next;
        i++;
    }
}

int main()
{
    int n;
    struct node *head;
    struct node *temp;
    printf("\n Enter the size of linkedList : ");
    scanf("%d",&n);
    head = malloc(sizeof(struct node) * n);

    // Storing head in temp
    temp = head;
    int i = 1; // Keep track on the position of the list
    while(temp != NULL) // Untill temp get to end of the list
    {
        printf("\n Enter the value in node %d : ", i);
        scanf("%d",&temp->data);
        temp = temp->next; // Assinging next list address
    }
    printList(head);
    return 0;
}

我不明白为什么在执行时它只打印一个值

我不知道我错了多少?

**输出:**

$ clang dynamicList.c -o a

$ ./a

Enter the size of linkedList : 10

Enter the value in node 1 : 9

Value in Node 1 : 9

【问题讨论】:

    标签: c struct linked-list dynamic-memory-allocation singly-linked-list


    【解决方案1】:

    这个malloc调用

    head = malloc(sizeof(struct node) * n);
    

    分配一个未初始化的内存。

    因此while循环中的这条语句

    temp = temp->next;
    

    为指针temp 分配一个不确定的值,并在循环中进一步使用该指针会调用未定义的行为。

    此外循环中的条件

    while(temp != NULL) // Untill temp get to end of the list
    

    没有意义。

    循环块范围内的这个声明

    int i = 1; // Keep track on the position of the list
    

    以及函数printList中的类似声明

    int i = 1;
    

    也说不通。

    您需要完全初始化n 节点。所以循环应该是这样的

    for ( int i = 0; i < n; i++ )
    {
        //...
    }
    

    当不再需要列表时,您还应该释放所有分配的内存。

    注意你分配了一个节点数组。使用您的方法,程序可以如下所示。

    #include <stdio.h>
    #include <stdlib.h>
    
    struct node 
    {
        int data;
        struct node *next;
    };
    
    // Printing the list
    void printList( const struct node *ptr ) 
    {
        for ( unsigned int i = 1; ptr != NULL; ptr = ptr->next )
        {
            printf( "Value in Node %u : %d\n", i++, ptr->data );
        }
    }
    
    int main( void ) 
    {
        unsigned int n = 0;
        struct node *head = NULL;
    
        printf( "Enter the size of linkedList : " );
        scanf( "%u", &n );
    
        head = malloc( n * sizeof( struct node ) );
        
        struct node *temp = head;
        for ( unsigned int i = 0; i < n; i++ )
        {
            printf( "Enter the value in node %u : ", i + 1 );
            scanf( "%d", &temp->data );
            temp->next = i == n - 1 ? NULL : temp + 1;
            ++temp;
        }
        
        printList( head );
        
        free( head );
        
        return 0;
    }
    

    程序输出可能看起来像

    Enter the size of linkedList : 10
    Enter the value in node 1 : 1
    Enter the value in node 2 : 2
    Enter the value in node 3 : 3
    Enter the value in node 4 : 4
    Enter the value in node 5 : 5
    Enter the value in node 6 : 6
    Enter the value in node 7 : 7
    Enter the value in node 8 : 8
    Enter the value in node 9 : 9
    Enter the value in node 10 : 10
    Value in Node 1 : 1
    Value in Node 2 : 2
    Value in Node 3 : 3
    Value in Node 4 : 4
    Value in Node 5 : 5
    Value in Node 6 : 6
    Value in Node 7 : 7
    Value in Node 8 : 8
    Value in Node 9 : 9
    Value in Node 10 : 10
    

    如果您确实想将数据组织为列表而不是数组,那么程序可以如下所示

    #include <stdio.h>
    #include <stdlib.h>
    
    struct node 
    {
        int data;
        struct node *next;
    };
    
    // Printing the list
    void printList( const struct node *ptr ) 
    {
        for ( unsigned int i = 1; ptr != NULL; ptr = ptr->next )
        {
            printf( "Value in Node %u : %d\n", i++, ptr->data );
        }
    }
    
    int main( void ) 
    {
        unsigned int n = 0;
        struct node *head = NULL;
    
        printf( "Enter the size of linkedList : " );
        scanf( "%u", &n );
    
        struct node *temp;
        for ( unsigned int i = 0; i < n; i++ )
        {
            if ( i == 0 )
            {
                head = malloc( sizeof( struct node ) );
                temp = head;
            }
            else
            {
                temp->next = malloc( sizeof( struct node ) );
                temp = temp->next;
            }
            printf( "Enter the value in node %u : ", i + 1 );
            scanf( "%d", &temp->data );
            
            temp->next = NULL;
        }
        
        printList( head );
        
        while ( head != NULL )
        {
            temp = head;
            head = head->next;
            free( temp );
        }       
        
        return 0;
    }
    

    程序输出可能与前面的演示程序一样。

    【讨论】:

      【解决方案2】:

      当您创建一个新节点时,您应该分配下一个节点,然后将当前节点移动到下一个节点。另外,您应该注意初始状态(当大小为 1 时)。你应该像这样修改你的代码:

      #include <stdio.h>
      #include <stdlib.h>
      
      struct node {
        int data;
        struct node* next;
      };
      
      // Printing the list
      void printList(struct node* ptr) {
        while (ptr != NULL) {
          int i = 1;
          printf("\n Value in Node %d : %d", i, ptr->data);
          ptr = ptr->next;
        }
      }
      
      int main() {
        int n;
        struct node* head;
        struct node* temp;
        printf("\n Enter the size of linkedList : ");
        scanf("%d", &n);
      
        int i = 1;     // Keep track on the position of the list
        while (i <= n) // Untill temp get to end of the list
        {
          if (i == 1) {
            head = malloc(sizeof(struct node) * n);
            temp = head;
          } else {
            temp->next = malloc(sizeof(struct node) * n);
            temp = temp->next;
          }
          printf("\n Enter the value in node %d : ", i);
          scanf("%d", &temp->data);
          ++i;
        }
        printList(head);
        return 0;
      }
      

      此外,您应该在程序结束时释放动态分配的内存以避免内存泄漏。

      【讨论】:

      • 每次使用malloc(sizeof(struct node) * n)为节点分配内存时。它是否只为单个节点分配内存?还是一次多个节点?如果 do --> malloc(sizeof(struct node)) 而不是高于 1 会发生什么?
      • 一个小问题,但在printList 中,您似乎不会在每个循环中增加i
      猜你喜欢
      • 2016-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      • 2017-06-02
      • 2015-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多