C语言 如何根据输入制作单向链表



我只是在学习链表,想用控制台的输入制作一个链表,但不知何故它不起作用。

#include <stdio.h>
#include <stdlib.h>
typedef struct datatype Node;
struct datatype {
int data;
Node *next;
};
int main() {
int i,n;
Node *node[50];
printf("Number of intergers: ");
scanf("%d",&n);
for(i=0; i<n; i++) {
printf("Enter interger one by one: ");
scanf("%d",&node[i]->data);
node[i]->next=node[i+1];
}

for(i=0;i<n;i++)
printf("%d->",node[i]->data);
}

基于Andreas的评论,这里有一个注释和内存安全的实现。你不一定要使用 malloc 和 free;您可以改用固定内存池:

#define MAX_NODE_SIZE 256
...
Node node[MAX_NODE_SIZE]; 

然后进行检查以确保用户输入的 n 永远不会大于 MAX_NODE_SIZE。但是,如果您尝试实现列表插入和删除,事情会变得复杂。此外,使用索引"i"遍历链表会破坏拥有链表的意义。

这是malloc/free版本:

#include <stdio.h>
#include <stdlib.h>
typedef struct datatype Node;
struct datatype {
int data;
Node *next;
};
int main() {
//Allocate the root node
Node *rootnode=malloc(sizeof(Node));
rootnode->data=0; rootnode->next=NULL; 
Node *currentnode=rootnode;
//Populate n and check for validity
printf("Number of integers: ");
int n;
scanf("%d",&n);
if(n<=0){
printf("List must have a nonzero/nonnegative number of elements.n");
return 1;
}
//Populate the list
for(int i=0; i<n; i++) {
printf("Enter integer one by one: ");
scanf("%d",&currentnode->data);
//If there is more data...
if(i!=n-1){
//Allocate room for the data
currentnode->next=malloc(sizeof(Node));
//Initialize things correctly
currentnode->next->data=0;
currentnode->next->next=NULL;
//Step to the next node.
currentnode=currentnode->next;
}
}
//Print the list
currentnode=rootnode;
do {
printf("%d",currentnode->data);
if(currentnode->next!=NULL)
printf(" -> ");
else
printf("n");
} while((currentnode=currentnode->next)!=NULL);
//Deallocate the list
currentnode=rootnode;
while(currentnode!=NULL){
Node *next=currentnode->next;
free(currentnode);
currentnode=next;
}
return 0;
}

示例输出:

user@desktop:~$ ./a.out
Number of integers: 3
Enter integer one by one: 1
Enter integer one by one: 2
Enter integer one by one: 3
1 -> 2 -> 3

您必须为链表的各个节点分配内存。相反,您为指向单个节点的 50 个指针分配内存,而不是为节点本身分配内存。

我建议你创建一个标准的链表,并对各个节点使用函数malloc,如下所示:

typedef struct Node {
int data;
struct Node *next;
} Node;
int main( void )
{
//this pointer always points to the first element, or NULL if there is no first element
Node *pRoot = NULL;
//this pointer always points to the NULL pointer at the end of the list, which is, when the list is empty, the root pointer
Node **ppNext = &pRoot;
Node *pCurrent;
int retval, n;
//ask user for total number of data elements
printf( "Number of integers: " );
retval = scanf( "%d", &n );
if ( retval != 1)
{
fprintf( stderr, "scanf failed!n" );
goto cleanup;
}
//build the list from user input
for ( int i = 0; i < n; i++ )
{
//allocate memory for new node
pCurrent = malloc( sizeof( Node ) );
if ( pCurrent == NULL )
{
fprintf( stderr, "malloc failed!n" );
goto cleanup;
}
//ask user for individual data elements
printf( "Enter integer one by one: " );
retval = scanf( "%d", &pCurrent->data );
if ( retval != 1 )
{
fprintf( stderr, "scanf failed!n" );
free( pCurrent );
goto cleanup;
}
pCurrent->next = NULL;
//link new node to linked list and update ppNext
*ppNext = pCurrent;
ppNext = &pCurrent->next;
}
//print the list
for ( pCurrent = pRoot; pCurrent != NULL; pCurrent = pCurrent->next )
{
printf( "%dn", pCurrent->data );
}
cleanup:
//free the linked list
for ( pCurrent = pRoot; pCurrent != NULL; )
{
Node *tmp = pCurrent;
pCurrent = pCurrent->next;
free( tmp );
}
return 0;
}

请注意,在我的代码中,在使用scanf写入的值之前,我检查了scanf的返回值。这是必要的,因为函数可能会失败并且不写入任何值,例如当用户输入字母而不是数字时。有关更多信息,请参阅此页面:

远离scanf()的初学者指南

最新更新