【问题标题】:C - simple linked list delete first element which contains 'k'C - 简单链表删除包含'k'的第一个元素
【发布时间】:2020-08-23 04:06:32
【问题描述】:

我想删除包含“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("%c\n", name);
    printf("Nun müsste \"Tilo ann\" kommen:\n");
    ausgabe(kopf);
}

所以我的问题如下: ausgabe(kopf) 给出输出:Tilo kann

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

但我得到的输出是:kann

那么,我该如何解决呢?

【问题讨论】:

  • 那么问题出在哪里?你的代码编译了吗?你的代码做的事情是否超出了你的预期?预期输出与实际输出是多少?阅读:How to Ask
  • 编辑:你说得对——我现在更准确地描述了这个问题。

标签: c struct linked-list singly-linked-list erase


【解决方案1】:

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

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

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

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

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

其中一种方法是返回例如字符'\0'

如果我理解正确,您需要的是以下内容

char popIfK( struct V_LISTE **kopf )
{
    char returnVal = '\0';

    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;
}

【讨论】:

    【解决方案2】:
    while (kElement->vorname != 'k')
    {
        kElement = kElement->nachfolger;
    }
    

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

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

    这样循环后你可以修改follower

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2019-10-29
        • 2020-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-11
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多