0

私は構造を持っています:

struct Node {
    int value;
    struct Node *next;
};

typedef struct Node List;

そして、リストにアイテムを追加することを実装しましたが、特定のリストの最初の要素である私の関数である場合、リストから要素を削除することに問題があります:

void removeItem(List *ptr, int i)
{
    List *current = ptr;
    List *prev = NULL;
while (current != NULL)
{
    if (current->value == i)
    {
                    //it's first element
        if (prev == NULL)
        {
            List *replace = ptr->next;
            free(current);
            ptr = replace;
            current = replace;
        }
        else
        {
            prev->next = current->next;
            free(current);
            current = prev->next;
        }
    }
    else
    {
        prev = current;
        current = current->next;
    }
}
}

私のリストが次のような場合:

1、2、3、4、5

removeItem(list, 1)を使用した後は次のようになります。

0、2、3、4、5

0があってはなりません。

もう 1 つの質問は、typedef が異なる場合にこれらの関数も実装する必要があるということです。

typedef struct Node *List;

しかし、その後、「間違った引数の型」/「構造体または共用体ではないメンバー「値」の要求」エラーが大量に発生します。これをどのように処理する必要があるかの例を見つけることができますか?

4

3 に答える 3

2

問題は、( list) で渡す変数が削除コードによって変更されないことです。したがって、最初の を削除するNodeと、には存在しないListへの参照が残ります。NodeList

その理由は次のとおりです。

を呼び出すとremoveItem(list, 1)、 の値が渡されますlist。この場合、 type のデータのアドレスですList。関数内ではremoveItem、その値はptr変数によって運ばれます。関数を入力すると、ptr変数はあなたのアドレスであり、Listそれを使って作業を行います。の行ptr = replaceでは、 が保持する値を変更するだけですptrlist呼び出されたスコープ内の値には影響しませんremoveItem

最も簡単なことremoveListは、結果リストの先頭へのポインターを返すことです。ほとんどの呼び出しでは、着信と同じになりptrます。削除されNodeた が の先頭にある場合にのみList、結果のポインターが異なります。

または、removeLista へのポインターへのポインターが必要になるように変更してからList、 as を呼び出すとremoveList(&list, 1)、値をlist直接変更できるようになります。

于 2013-01-18T19:02:19.210 に答える
1

これは宿題のように見えるので、直接的な回答はしたくありませんが、2 つの手がかりがあります。

  • あなたの目標が関数呼び出しでリストが指すものを変更することである場合removeItem()、 の最初の引数の型は何にremoveItem()する必要がありますか?

  • 一部の実装ではfree()、ポインター変数を使用すると、その変数が指すスペースがゼロになり、デバッグが容易になると言った場合、得られる出力を理解するのに役立ちますか?

これが機能するようになったら、お気軽に自分の質問への回答を投稿してください。

于 2013-01-18T19:02:56.000 に答える
0

すべての回答は役に立ちました。これは最終的な機能です:

void removeItem(List *ptr, int i)
{
    while ((*ptr) != NULL)
    {
        if ((*ptr)->value == i)
        {
            List tmp = *ptr;
            *ptr = (*ptr)->next;
            free(tmp);
        }
        else
        {
            ptr = &((*ptr)->next);
        }
    }
}

正常に動作します:

List ptr = malloc(sizeof(List));

//add items to list:
//1, 1, 2, 3, 4, 4, 5, 5,

removeItem(&ptr, 5);
removeItem(&ptr, 2);
removeItem(&ptr, 1);

//print and clean
//3, 4, 4, 
于 2013-01-20T16:33:24.657 に答える