如何将数据动态存储在C中的链表中?

Posted

技术标签:

【中文标题】如何将数据动态存储在C中的链表中?【英文标题】:How to store the data dynamically in linked list in 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

【问题讨论】:

【参考方案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

以上是关于如何将数据动态存储在C中的链表中?的主要内容,如果未能解决你的问题,请参考以下文章

从 O(1) 中的链表中删除任何元素 - Java vs C++

从c中的链表中删除名称时出错

c语言中链表的问题

如何从java中的链表中删除一个对象?

C和C指针小记(十七)-使用结构和指针

如何将字符串从文件复制到 C 中的链表?