C - 简单链表删除包含"k"的第一个元素



我想删除包含"k"的简单链表中的元素。我能够获得name = popIfK(&kopf);中的"k"现在在函数popIfK(...)中,我必须指向前面的元素和后面的元素。我该如何解决此问题?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct V_LISTE
{
char vorname;
struct V_LISTE *nachfolger;
};
struct V_LISTE *insert(struct V_LISTE *list, char key)
{
struct V_LISTE *newElement;
newElement = (struct V_LISTE *) malloc(sizeof(struct V_LISTE));
newElement->vorname = key;
newElement->nachfolger = list;
list = newElement;
return list;
}

char popIfK(struct V_LISTE **kopf)
{
char *returnVal;
struct V_LISTE *kElement;
kElement = (*kopf)->nachfolger;
while (kElement->vorname != 'k')
{
kElement = kElement->nachfolger;
}
returnVal = &kElement->vorname;
// Nun muss das Element davor auf das danach zeigen 
// und Speicher von dem Element mit k muss freigegeben werden
free(*kopf);
*kopf = kElement;
return *returnVal;
}
void ausgabe(struct V_LISTE *list)
{
while (list != NULL)
{
printf("%c", list->vorname);
list = list->nachfolger;
}
printf("n");
} 
int main()
{
struct V_LISTE *kopf;
kopf = (struct V_LISTE *) malloc(sizeof(struct V_LISTE));
kopf->vorname = 'n';
kopf->nachfolger = NULL;
kopf = insert(kopf, 'n');
kopf = insert(kopf, 'a');
kopf = insert(kopf, 'k');
kopf = insert(kopf, ' ');
kopf = insert(kopf, 'o');
kopf = insert(kopf, 'l');
kopf = insert(kopf, 'i');
kopf = insert(kopf, 'T');
ausgabe(kopf);
printf("Nun müsste ein 'k' kommen:n");
name = popIfK(&kopf);
printf("%cn", name);
printf("Nun müsste "Tilo ann" kommen:n");
ausgabe(kopf);
}

因此,我的问题如下:ausgabe(kopf)给出输出:Tilo-kann

在第二次调用ausgabe(kopf)时使用函数name = popIfK(&kopf);后,我期望输出:Tilo-ann

但我得到的输出是:kann

那么,我该如何解决这个问题呢?

您需要第二个指针,它跟在kElement后面的一个节点后面。这样,当您找到要删除的节点时,可以执行类似prev->nachfolger = kElement->nachfolger的操作。

while (kElement->vorname != 'k')
{
kElement = kElement->nachfolger;
}

在这个搜索中,您还应该保留kElement后面的另一个变量。试试这个

{
follower=kElement;
kElement=kElement -> nachfolger;
}

这样循环后就可以修改follower

对于初学者来说,使用英文单词来命名标识符。否则,其他程序员很难阅读您的代码。

你的函数定义至少是由于这个代码片段中的最后一条语句

char popIfK(struct V_LISTE **kopf)
{
char *returnVal;
struct V_LISTE *kElement;
kElement = (*kopf)->nachfolger;
//...

可以在为空列表调用函数时调用未定义的行为。当列表中不包含值为'k'的节点时,它还会调用未定义的行为。或者,当它是第一个包含值'k'的节点时,它甚至不会工作。

请考虑,如果列表中不包含值为'k'的节点,则应该决定从函数返回什么。

方法之一是返回例如字符''

如果我理解正确,你需要的是以下

char popIfK( struct V_LISTE **kopf )
{
char returnVal = '';
while ( *kopf != NULL && ( *kopf )->vorname != 'k' )
{
kopf = &( *kopf )->nachfolger;
}
if ( *kopf != NULL )
{
returnVal = ( *kopf )->vorname;
struct V_LISTE *kElement = *kopf;
*kopf = ( *kopf )->nachfolger;
free( kElement );
}
return returnVal;
}

在我看来,这个功能没有多大意义。您可以编写一个更通用的函数,从列表中删除具有给定字符值的节点。

这样的函数可以按照以下方式

int remove( struct V_LISTE **kopf, char vorname )
{
while ( *kopf != NULL && ( *kopf )->vorname != vorname )
{
kopf = &( *kopf )->nachfolger;
}
int success = *kopf != NULL;
if ( success )
{
struct V_LISTE *kElement = *kopf;
*kopf = ( *kopf )->nachfolger;
free( kElement );
}
return success;
}

相关内容

  • 没有找到相关文章

最新更新