gpt4 book ai didi

c - 从双链表中删除

转载 作者:太空宇宙 更新时间:2023-11-04 02:20:51 26 4
gpt4 key购买 nike

我试图从双向链表中删除一个节点,但我遇到了问题这个问题是当节点是第一个或中间节点时它打印 0 而不是真正删除,但是当它是列表中的最后一个节点时它工作得很好,这是代码:

dList* del(dList*ptr, int x)
{

dList *itr = NULL;
for( itr = ptr; itr != NULL; itr = itr -> next)
{
// if the element is the first in the list
if(itr -> value == x && itr -> prev == NULL)
{
itr -> next -> prev = NULL;
ptr = itr -> next;
free(itr);
}
// if the element is the last in the list
else if(itr -> value == x && itr -> next == NULL)
{
itr -> prev -> next = NULL;

free(itr);
}
// if its in the middle

else if(itr -> value == x){
(itr -> prev) -> next = itr -> next;
(itr -> next) -> prev = itr -> prev;
free(itr);
}
}
return ptr;
}

提前致谢!

最佳答案

这个循环

for( itr = ptr; itr != NULL; itr = itr -> next)
{
// if the element is the first in the list
if(itr -> value == x && itr -> prev == NULL)
{
itr -> next -> prev = NULL;
ptr = itr -> next;
free(itr);
}
// ...

有未定义的行为。

例如for循环的第三个表达式

itr = itr -> next

你正在使用已经删除的指针

free(itr);

例如,如果列表只有一个节点,则 itr->next 等于 NULL。所以再次声明

itr -> next -> prev = NULL;

还调用未定义的行为。

如果通过指向头节点的指针按引用传递头节点,函数看起来会简单得多。

还有一个更有用的返回值是列表中删除的节点数。

函数定义如下所示

size_t del( dList **ptr, int value )
{
size_t n = 0;

while ( *ptr != NULL )
{
if ( ( *ptr )->value == value )
{
dList *tmp = *ptr;
*ptr = ( *ptr )->next;
if ( *ptr ) ( *ptr )->prev = tmp->prev;

free( tmp );
++n;
}
else
{
ptr = &( *ptr )->next;
}
}

return n;
}

这是一个演示程序。

#include <stdio.h>
#include <stdlib.h>

typedef struct dList
{
int value;
struct dList *prev;
struct dList *next;
} dList;


size_t del( dList **ptr, int value )
{
size_t n = 0;

while ( *ptr != NULL )
{
if ( ( *ptr )->value == value )
{
dList *tmp = *ptr;
*ptr = ( *ptr )->next;
if ( *ptr ) ( *ptr )->prev = tmp->prev;

free( tmp );
++n;
}
else
{
ptr = &( *ptr )->next;
}
}

return n;
}

int push_front( dList **head, int value )
{
dList *new_node = malloc( sizeof( dList ) );
int success = new_node != NULL;

if ( success )
{
new_node->prev = NULL;
new_node->value = value;
new_node->next = *head;

if ( *head ) ( *head )->prev = new_node;

*head = new_node;
}

return success;
}

void out( dList *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d --> ", head->value );
}

puts( "NULL" );
}

int main(void)
{
dList *head = NULL;

push_front( &head, 1 );
push_front( &head, 2 );
push_front( &head, 1 );

out( head );

size_t n = del( &head, 1 );

printf( "%zu nodes are deleted.\n", n );
out( head );

n = del( &head, 2 );

printf( "%zu nodes are deleted.\n", n );
out( head );

return 0;
}

它的输出是

1 --> 2 --> 1 --> NULL
2 nodes are deleted.
2 --> NULL
1 nodes are deleted.
NULL

关于c - 从双链表中删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58394877/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com