从链表中删除一个元素
Removing an element from a linked list
假设我有下面这个列表:
List of CDData
1: Test1
2: Test2
3: Test3
4: Test4
5: Test5
6: Test6
现在我想使用链表从列表中删除第三个:这意味着
免费(从 DList 中删除(3));
这是我的职能:
TCD *removeFromDList(int res)
{
int count = 0;
TCD *CDData = First;
CDData->Prev = First;
if (First == NULL)
{
printf("Error\n");
return NULL;
}
while (CDData)
{
count++;
if (count == res)
{
if (count == 1)
{
if (CDData == Last)
Last = NULL;
First = First->Next;
return CDData;
}
else
{
while (CDData != NULL)
{
CDData->Prev = CDData->Next;
if (CDData == Last)
Last = CDData->Prev;
// printf("%s",CDData->Title) I tested here whether my function is going to
// delete the third one or not with the printf() and it's actually printing the third one
// Which means it's correct
return CDData;
}
}
}
else
CDData->Prev = CDData;
CDData = CDData->Next;
}
}
顺便说一句,这是TCD的定义
typedef struct F
{
char *Title;
struct F *Next;
struct F *Prev;
}TCD;
现在重新打印我的列表后,似乎所有 CDData(整个数据结构)都已被释放。有什么想法吗?
我得到这个作为输出
List of CDData
我认为在这个结构定义中
typedef struct F
{
char *Titel;
struct F *Next;
struct F *Prev;
}TCD;
你的意思是第一个数据成员的名字是Title
而不是Titel
。
并且您需要为该数据成员指向的字符串动态分配内存。
您的函数至少可以调用未定义的行为,因为最初全局变量 First
(顺便说一句,当函数依赖于全局变量时,这是一个坏主意)可以等于 NULL
。所以在这个代码片段中
TCD *CDData = First;
CDData->Prev = First;
试图使用空指针 (CDData->Prev
) 访问内存。
这个内部 while 循环
while (CDData != NULL)
{
CDData->Prev = CDData->Next;
if (CDData == Last)
Last = CDData->Prev;
// printf("%s",CDData->Title) I tested here whether my function is going to
// delete the third one or not with the printf() and it's actually printing the third one
// Which means it's correct
return CDData;
}
没有意义。
注意C中索引是从0开始的
使用您的方法,可以按以下方式编写函数,如下面的演示程序所示。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct F
{
char *Title;
struct F *Next;
struct F *Prev;
} TCD;
TCD *First, *Last;
TCD * removeFromDList( size_t n )
{
TCD **Current = &First;
while ( *Current && n--)
{
Current = &( *Current )->Next;
}
TCD *target = *Current;
if ( *Current )
{
if ( ( *Current )->Next == NULL )
{
Last = ( *Current )->Prev;
}
else
{
( *Current )->Next->Prev = ( *Current )->Prev;
}
*Current = ( *Current )->Next;
}
return target;
}
int append( const char *s )
{
TCD *Current = malloc( sizeof( TCD ) );
int success = Current != NULL;
if ( success )
{
Current->Title = malloc( strlen( s ) + 1 );
success = Current->Title != NULL;
if ( success )
{
strcpy( Current->Title, s );
Current->Prev = Last;
Current->Next = NULL;
}
else
{
free( Current );
}
}
if ( success )
{
if ( Last )
{
Last = Last->Next = Current;
}
else
{
First = Last = Current;
}
}
return success;
}
FILE * display( FILE *fp )
{
for ( TCD *Current = First; Current; Current = Current->Next )
{
fprintf( fp, "%s -> ", Current->Title );
}
fputs( "NULL", fp );
return fp;
}
int main(void)
{
for ( char s[] = "A"; s[0] != 'E'; ++*s )
{
append( s );
}
fputc( '\n', display( stdout ) );
TCD *p = removeFromDList( 3 );
free( p->Title );
free( p );
fputc( '\n', display( stdout ) );
p = removeFromDList( 1 );
free( p->Title );
free( p );
fputc( '\n', display( stdout ) );
p = removeFromDList( 0 );
free( p->Title );
free( p );
fputc( '\n', display( stdout ) );
p = removeFromDList( 0 );
free( p->Title );
free( p );
fputc( '\n', display( stdout ) );
printf( "First == NULL : %d, Last == NULL : %d\n", First == NULL, Last == NULL );
return 0;
}
程序输出为
A -> B -> C -> D -> NULL
A -> B -> C -> NULL
A -> C -> NULL
C -> NULL
NULL
First == NULL : 1, Last == NULL : 1
假设我有下面这个列表:
List of CDData
1: Test1
2: Test2
3: Test3
4: Test4
5: Test5
6: Test6
现在我想使用链表从列表中删除第三个:这意味着 免费(从 DList 中删除(3)); 这是我的职能:
TCD *removeFromDList(int res)
{
int count = 0;
TCD *CDData = First;
CDData->Prev = First;
if (First == NULL)
{
printf("Error\n");
return NULL;
}
while (CDData)
{
count++;
if (count == res)
{
if (count == 1)
{
if (CDData == Last)
Last = NULL;
First = First->Next;
return CDData;
}
else
{
while (CDData != NULL)
{
CDData->Prev = CDData->Next;
if (CDData == Last)
Last = CDData->Prev;
// printf("%s",CDData->Title) I tested here whether my function is going to
// delete the third one or not with the printf() and it's actually printing the third one
// Which means it's correct
return CDData;
}
}
}
else
CDData->Prev = CDData;
CDData = CDData->Next;
}
}
顺便说一句,这是TCD的定义
typedef struct F
{
char *Title;
struct F *Next;
struct F *Prev;
}TCD;
现在重新打印我的列表后,似乎所有 CDData(整个数据结构)都已被释放。有什么想法吗?
我得到这个作为输出
List of CDData
我认为在这个结构定义中
typedef struct F
{
char *Titel;
struct F *Next;
struct F *Prev;
}TCD;
你的意思是第一个数据成员的名字是Title
而不是Titel
。
并且您需要为该数据成员指向的字符串动态分配内存。
您的函数至少可以调用未定义的行为,因为最初全局变量 First
(顺便说一句,当函数依赖于全局变量时,这是一个坏主意)可以等于 NULL
。所以在这个代码片段中
TCD *CDData = First;
CDData->Prev = First;
试图使用空指针 (CDData->Prev
) 访问内存。
这个内部 while 循环
while (CDData != NULL)
{
CDData->Prev = CDData->Next;
if (CDData == Last)
Last = CDData->Prev;
// printf("%s",CDData->Title) I tested here whether my function is going to
// delete the third one or not with the printf() and it's actually printing the third one
// Which means it's correct
return CDData;
}
没有意义。
注意C中索引是从0开始的
使用您的方法,可以按以下方式编写函数,如下面的演示程序所示。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct F
{
char *Title;
struct F *Next;
struct F *Prev;
} TCD;
TCD *First, *Last;
TCD * removeFromDList( size_t n )
{
TCD **Current = &First;
while ( *Current && n--)
{
Current = &( *Current )->Next;
}
TCD *target = *Current;
if ( *Current )
{
if ( ( *Current )->Next == NULL )
{
Last = ( *Current )->Prev;
}
else
{
( *Current )->Next->Prev = ( *Current )->Prev;
}
*Current = ( *Current )->Next;
}
return target;
}
int append( const char *s )
{
TCD *Current = malloc( sizeof( TCD ) );
int success = Current != NULL;
if ( success )
{
Current->Title = malloc( strlen( s ) + 1 );
success = Current->Title != NULL;
if ( success )
{
strcpy( Current->Title, s );
Current->Prev = Last;
Current->Next = NULL;
}
else
{
free( Current );
}
}
if ( success )
{
if ( Last )
{
Last = Last->Next = Current;
}
else
{
First = Last = Current;
}
}
return success;
}
FILE * display( FILE *fp )
{
for ( TCD *Current = First; Current; Current = Current->Next )
{
fprintf( fp, "%s -> ", Current->Title );
}
fputs( "NULL", fp );
return fp;
}
int main(void)
{
for ( char s[] = "A"; s[0] != 'E'; ++*s )
{
append( s );
}
fputc( '\n', display( stdout ) );
TCD *p = removeFromDList( 3 );
free( p->Title );
free( p );
fputc( '\n', display( stdout ) );
p = removeFromDList( 1 );
free( p->Title );
free( p );
fputc( '\n', display( stdout ) );
p = removeFromDList( 0 );
free( p->Title );
free( p );
fputc( '\n', display( stdout ) );
p = removeFromDList( 0 );
free( p->Title );
free( p );
fputc( '\n', display( stdout ) );
printf( "First == NULL : %d, Last == NULL : %d\n", First == NULL, Last == NULL );
return 0;
}
程序输出为
A -> B -> C -> D -> NULL
A -> B -> C -> NULL
A -> C -> NULL
C -> NULL
NULL
First == NULL : 1, Last == NULL : 1