为什么我的 DeleteNode() 函数不工作?
Why isn't my DeleteNode() function working?
我创建了一个单向链表,其中 3 个节点的值分别为 45,90,100。我正在编写一个函数,它将删除列表的最后一个节点。但是输出打印了所有 3 个值。
void DeleteNode()
{
struct node *ptr1=head,*ptr2=head;
while(ptr1!=NULL&&ptr2->link!=NULL)
I have created two pointers ptr1 and ptr2 of struct node type for traversal. The loop is defined to run until ptr1 reaches last node and points to NULL and ptr2->link i.e. the last node points to NULL.
{
ptr1=ptr1->link;
ptr2=ptr2->link;
}
ptr2=NULL;
When the loop breaks, ptr2 will point to NULL and hence the last node should get deleted. But that doesn't happen.
}
“ptr2 将指向 NULL,因此最后一个节点应该被删除。”
没有。
你取消了一个局部变量的指针(在你取消它之前恰好指向 linked 列表中的某些东西),并且 not link linked 列表结构的指针部分:它对 linked 列表没有影响。
请注意,一旦更正此问题,您将发生内存泄漏(删除的节点)。
另外,ptr1 和 ptr2 总是指向同一个东西,保留两者是没有意义的。您最初可能有 ptr2==ptr1->link 或相反的想法,但这不是必需的,您的测试 ptr1 != NULL && ptr2->link != NULL
实际上等同于 ptr1 != NULL && ptr1->link != NULL
.
ptr2
是函数的局部变量。将其值设置为 NULL
不会更改列表节点的数据成员 link
。
此外,如果列表仅包含一个节点,则不会将其从列表中删除,因为全局变量 head
不会更改。
使用您的方法(您没有说明列表是如何创建的)函数可以如下所示
void DeleteNode( void )
{
struct node *ptr1 = head;
if ( ptr1 )
{
struct node *ptr2 = head->link;
if ( ptr2 == NULL )
{
head = NULL;
}
else
{
while ( ptr2->link != NULL )
{
ptr1 = ptr1->link;
ptr2 = ptr2->link;
}
ptr1->link = NULL;
}
}
}
这是一个演示程序。
#include <stdio.h>
struct node
{
int data;
struct node *link;
} *head;
void display( void )
{
for ( struct node *current = head; current != NULL; current = current->link )
{
printf( "%d -> ", current->data );
}
puts( "null" );
}
void DeleteNode( void )
{
struct node *ptr1 = head;
if ( ptr1 )
{
struct node *ptr2 = head->link;
if ( ptr2 == NULL )
{
head = NULL;
}
else
{
while ( ptr2->link != NULL )
{
ptr1 = ptr1->link;
ptr2 = ptr2->link;
}
ptr1->link = NULL;
}
}
}
int main(void)
{
struct node n3 = { 100, NULL };
struct node n2 = { 90, &n3 };
struct node n1 = { 45, &n2 };
head = &n1;
display();
DeleteNode();
display();
DeleteNode();
display();
DeleteNode();
display();
return 0;
}
程序输出为
45 -> 90 -> 100 -> null
45 -> 90 -> null
45 -> null
null
如果通过引用访问列表中的指针,函数可以定义得更简单。例如
void DeleteNode( void )
{
struct node **current = &head;
while ( *current && ( *current )->link )
{
current = &( *current )->link;
}
*current = NULL;
}
注意,如果是动态分配的,函数不会释放被删除的节点。在一般情况下,列表由动态分配的节点组成,DeleteNode
等函数应释放它们。
我创建了一个单向链表,其中 3 个节点的值分别为 45,90,100。我正在编写一个函数,它将删除列表的最后一个节点。但是输出打印了所有 3 个值。
void DeleteNode()
{
struct node *ptr1=head,*ptr2=head;
while(ptr1!=NULL&&ptr2->link!=NULL)
I have created two pointers ptr1 and ptr2 of struct node type for traversal. The loop is defined to run until ptr1 reaches last node and points to NULL and ptr2->link i.e. the last node points to NULL.
{
ptr1=ptr1->link;
ptr2=ptr2->link;
}
ptr2=NULL;
When the loop breaks, ptr2 will point to NULL and hence the last node should get deleted. But that doesn't happen.
}
“ptr2 将指向 NULL,因此最后一个节点应该被删除。”
没有。
你取消了一个局部变量的指针(在你取消它之前恰好指向 linked 列表中的某些东西),并且 not link linked 列表结构的指针部分:它对 linked 列表没有影响。
请注意,一旦更正此问题,您将发生内存泄漏(删除的节点)。
另外,ptr1 和 ptr2 总是指向同一个东西,保留两者是没有意义的。您最初可能有 ptr2==ptr1->link 或相反的想法,但这不是必需的,您的测试 ptr1 != NULL && ptr2->link != NULL
实际上等同于 ptr1 != NULL && ptr1->link != NULL
.
ptr2
是函数的局部变量。将其值设置为 NULL
不会更改列表节点的数据成员 link
。
此外,如果列表仅包含一个节点,则不会将其从列表中删除,因为全局变量 head
不会更改。
使用您的方法(您没有说明列表是如何创建的)函数可以如下所示
void DeleteNode( void )
{
struct node *ptr1 = head;
if ( ptr1 )
{
struct node *ptr2 = head->link;
if ( ptr2 == NULL )
{
head = NULL;
}
else
{
while ( ptr2->link != NULL )
{
ptr1 = ptr1->link;
ptr2 = ptr2->link;
}
ptr1->link = NULL;
}
}
}
这是一个演示程序。
#include <stdio.h>
struct node
{
int data;
struct node *link;
} *head;
void display( void )
{
for ( struct node *current = head; current != NULL; current = current->link )
{
printf( "%d -> ", current->data );
}
puts( "null" );
}
void DeleteNode( void )
{
struct node *ptr1 = head;
if ( ptr1 )
{
struct node *ptr2 = head->link;
if ( ptr2 == NULL )
{
head = NULL;
}
else
{
while ( ptr2->link != NULL )
{
ptr1 = ptr1->link;
ptr2 = ptr2->link;
}
ptr1->link = NULL;
}
}
}
int main(void)
{
struct node n3 = { 100, NULL };
struct node n2 = { 90, &n3 };
struct node n1 = { 45, &n2 };
head = &n1;
display();
DeleteNode();
display();
DeleteNode();
display();
DeleteNode();
display();
return 0;
}
程序输出为
45 -> 90 -> 100 -> null
45 -> 90 -> null
45 -> null
null
如果通过引用访问列表中的指针,函数可以定义得更简单。例如
void DeleteNode( void )
{
struct node **current = &head;
while ( *current && ( *current )->link )
{
current = &( *current )->link;
}
*current = NULL;
}
注意,如果是动态分配的,函数不会释放被删除的节点。在一般情况下,列表由动态分配的节点组成,DeleteNode
等函数应释放它们。