将节点添加到列表的问题
issue with adding node to a list
我有一段代码,我试图在其中添加一个节点以从空链表创建列表。随后它不断添加到列表的末尾。我有一个代码块,只保留最后两个节点。假设如果我添加两个元素 - 10、11 它工作正常。但是当我执行 11、12、13、14 时,它只保留 13、14。我有一个工作正常的工作,但想知道是什么导致了这种行为。代码块如下。问题仅与 AddList 函数有关。
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void AddList(struct Node** node, int value) {
struct Node* new = (struct Node*)malloc(sizeof(struct Node));
new->data = value;
new->next = NULL;
if (*node == NULL) {
*node = new;
return;
}
while ((*node)->next != NULL) {
*node = (*node)->next;
}
(*node)->next = new;
return;
}
void PrintList(struct Node** node) {
printf("\n\n");
if (node == NULL) {
printf("\n\nList is empty !! Nothing to Print. \n\n");
return;
}
while (*node != NULL) {
printf("%d--> ", (*node)->data);
*node = (*node)->next;
}
printf("\n\n");
return;
}
void main() {
struct Node* head = NULL;
AddList(&head, 10);
AddList(&head, 11);
AddList(&head, 12);
AddList(&head, 13);
AddList(&head, 14);
PrintList(&head);
}
本次修改修正了问题:添加了一个新变量 struct Node* current
void AddList(struct Node** node, int value) {
struct Node* new = (struct Node*)malloc(sizeof(struct Node));
struct Node* current = *node;
new->data = value;
new->next = NULL;
if (*node == NULL) {
*node = new;
return;
}
while(current->next != NULL) {
current = current->next;
}
current->next = new;
return;
}
您在函数 AddList
和 PrintList
中都犯了同样的错误。这两个函数都通过引用接受指向头节点的指针,例如
AddList(&head, 14);
PrintList(&head);
因此,如果函数将指向的指针更改为头节点,那么它的值也会更改。
事实上,指向头节点的指针在函数内发生了变化。
在函数AddList
这个循环
while ((*node)->next != NULL) {
*node = (*node)->next;
^^^^^^^^^^^^^^^^^^^^^^
}
更改指向头节点的指针的值。
在函数PrintList
中,由于这个while循环,指向头节点的指针甚至被设置为NULL
while (*node != NULL) {
printf("%d--> ", (*node)->data);
*node = (*node)->next;
^^^^^^^^^^^^^^^^^^^^^^
}
还有函数PrintList
if语句中的条件
if ( node == NULL) {
printf("\n\nList is empty !! Nothing to Print. \n\n");
return;
}
没有意义。即指针节点可以等于NULL,但这并不意味着当前列表为空。
函数可以这样定义
int AddList( struct Node **head, int data )
{
struct Node *new_node = ( struct Node* )malloc( sizeof( struct Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = NULL;
while ( *head ) head = &( *head )->next;
*head = new_node;
}
return success;
}
和
void PrintList( const struct Node *head )
{
printf("\n\n");
if ( head == NULL )
{
printf("\n\nList is empty !! Nothing to Print. \n\n");
}
else
{
for ( ; head != NULL; head = head->next )
{
printf( "%d--> ", head->data );
}
printf("\n\n");
}
}
不需要通过引用将指向头节点的指针传递给函数PrintList
。即可以调用函数,例如
AddList( &head, 14 );
^^^^^
和
PrintList( head );
^^^^
如果你要在列表的尾部添加新节点,那么定义一个双向单链表会好得多。那就是您可以再引入一种结构,例如
struct Node
{
int data;
struct Node* next;
};
和
struct List
{
struct Node *head;
struct Node *tail;
};
在这种情况下,将新节点添加到列表尾部的函数会更有效率,因为不需要遍历列表的所有节点。
请记住,根据 C 标准,函数 main
应声明为
int main( void )
而不是
void main()
我有一段代码,我试图在其中添加一个节点以从空链表创建列表。随后它不断添加到列表的末尾。我有一个代码块,只保留最后两个节点。假设如果我添加两个元素 - 10、11 它工作正常。但是当我执行 11、12、13、14 时,它只保留 13、14。我有一个工作正常的工作,但想知道是什么导致了这种行为。代码块如下。问题仅与 AddList 函数有关。
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void AddList(struct Node** node, int value) {
struct Node* new = (struct Node*)malloc(sizeof(struct Node));
new->data = value;
new->next = NULL;
if (*node == NULL) {
*node = new;
return;
}
while ((*node)->next != NULL) {
*node = (*node)->next;
}
(*node)->next = new;
return;
}
void PrintList(struct Node** node) {
printf("\n\n");
if (node == NULL) {
printf("\n\nList is empty !! Nothing to Print. \n\n");
return;
}
while (*node != NULL) {
printf("%d--> ", (*node)->data);
*node = (*node)->next;
}
printf("\n\n");
return;
}
void main() {
struct Node* head = NULL;
AddList(&head, 10);
AddList(&head, 11);
AddList(&head, 12);
AddList(&head, 13);
AddList(&head, 14);
PrintList(&head);
}
本次修改修正了问题:添加了一个新变量 struct Node* current
void AddList(struct Node** node, int value) {
struct Node* new = (struct Node*)malloc(sizeof(struct Node));
struct Node* current = *node;
new->data = value;
new->next = NULL;
if (*node == NULL) {
*node = new;
return;
}
while(current->next != NULL) {
current = current->next;
}
current->next = new;
return;
}
您在函数 AddList
和 PrintList
中都犯了同样的错误。这两个函数都通过引用接受指向头节点的指针,例如
AddList(&head, 14);
PrintList(&head);
因此,如果函数将指向的指针更改为头节点,那么它的值也会更改。
事实上,指向头节点的指针在函数内发生了变化。
在函数AddList
这个循环
while ((*node)->next != NULL) {
*node = (*node)->next;
^^^^^^^^^^^^^^^^^^^^^^
}
更改指向头节点的指针的值。
在函数PrintList
中,由于这个while循环,指向头节点的指针甚至被设置为NULL
while (*node != NULL) {
printf("%d--> ", (*node)->data);
*node = (*node)->next;
^^^^^^^^^^^^^^^^^^^^^^
}
还有函数PrintList
if语句中的条件
if ( node == NULL) {
printf("\n\nList is empty !! Nothing to Print. \n\n");
return;
}
没有意义。即指针节点可以等于NULL,但这并不意味着当前列表为空。
函数可以这样定义
int AddList( struct Node **head, int data )
{
struct Node *new_node = ( struct Node* )malloc( sizeof( struct Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = NULL;
while ( *head ) head = &( *head )->next;
*head = new_node;
}
return success;
}
和
void PrintList( const struct Node *head )
{
printf("\n\n");
if ( head == NULL )
{
printf("\n\nList is empty !! Nothing to Print. \n\n");
}
else
{
for ( ; head != NULL; head = head->next )
{
printf( "%d--> ", head->data );
}
printf("\n\n");
}
}
不需要通过引用将指向头节点的指针传递给函数PrintList
。即可以调用函数,例如
AddList( &head, 14 );
^^^^^
和
PrintList( head );
^^^^
如果你要在列表的尾部添加新节点,那么定义一个双向单链表会好得多。那就是您可以再引入一种结构,例如
struct Node
{
int data;
struct Node* next;
};
和
struct List
{
struct Node *head;
struct Node *tail;
};
在这种情况下,将新节点添加到列表尾部的函数会更有效率,因为不需要遍历列表的所有节点。
请记住,根据 C 标准,函数 main
应声明为
int main( void )
而不是
void main()