我创建了一个单独链接的列表,其中有3个节点,值分别为45,90100。我正在编写一个函数,该函数将删除列表的最后一个节点。但是输出会打印所有3个值。
void DeleteNode()
{
struct node *ptr1=head,*ptr2=head;
while(ptr1!=NULL&&ptr2->link!=NULL)
我创建了两个指针ptr1和ptr2,这两个指针属于结构节点类型,用于遍历。循环被定义为运行,直到ptr1到达最后一个节点并指向NULL和ptr2->链接,即最后一个节点指向NULL。
{
ptr1=ptr1->link;
ptr2=ptr2->link;
}
ptr2=NULL;
当循环中断时,ptr2将指向NULL,因此最后一个节点应该被删除。但这并没有发生。
}
"ptr2将指向NULL,因此最后一个节点应该被删除">
没有。
您可以取消一个局部变量指针(在取消它之前恰好指向链表中的某个内容(,并且而不是链表结构的链接指针部分:它对链表没有影响。
请注意,一旦更正此问题,就会出现内存泄漏(删除的节点(。
此外,ptr1和ptr2总是指向同一个东西,保留两者是没有意义的。您最初可能有这样的想法:ptr2==ptr1->链接或其他方式,但这不是必要的,并且您的测试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
等功能将释放这些节点。