我有一段代码,试图在其中添加一个节点,以便从空链表中生成列表。随后,它不断添加到列表的末尾。我有一个代码块,只保留最后两个节点。假设我加上两个元素——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("nn");
if (node == NULL) {
printf("nnList is empty !! Nothing to Print. nn");
return;
}
while (*node != NULL) {
printf("%d--> ", (*node)->data);
*node = (*node)->next;
}
printf("nn");
return;
}
void main() {
struct Node* head = NULL;
AddList(&head, 10);
AddList(&head, 11);
AddList(&head, 12);
AddList(&head, 13);
AddList(&head, 14);
PrintList(&head);
}
您在函数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("nnList is empty !! Nothing to Print. nn");
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("nn");
if ( head == NULL )
{
printf("nnList is empty !! Nothing to Print. nn");
}
else
{
for ( ; head != NULL; head = head->next )
{
printf( "%d--> ", head->data );
}
printf("nn");
}
}
不需要通过引用将指向头节点的指针传递给函数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()
此修改更正了问题:添加了一个新的变量结构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;
}