-1

リンクされたリストの例に取り組んでいます。私は、特定の要素を見つけるためにリストを走査する検索および削除機能を使用しています。find_remove 関数は機能しません。アプリケーション内の他のすべての関数 (head_return、tail_return など) は機能します。

誰かがfind_removeのどこが間違っているかを指摘できれば幸いです。

#include <iostream>
using namespace std;

struct node_ll
{
    int payload;
    node_ll* next;//Pointer to the next node
};

void head_insert(node_ll** list, int pload)
{
    node_ll* temp = new node_ll;//Create a new node, and let temp be the address of that node.
    temp->payload = pload;//Set the payload of the struct whose address is temp to pload.
    temp->next = *list;//Set the next of the struct whose address is temp to the address of the old head of the list.
    *list = temp;//The address of the old head of the list is changed to the address of the struct temp.
};

void tail_insert(node_ll** list, int pload)
{
    if (*list == NULL)
    {
        head_insert(list, pload);
    }
    else
    {
        node_ll* temp = new node_ll;
        for (temp = *list; temp->next; temp = temp->next);
        temp->next = new node_ll;
        temp->next->payload = pload;
        temp->next->next = NULL;
    }
}

int head_return (node_ll** list)
{
    if (*list != NULL)
    {
    int temp = (*list)->payload;
      node_ll* trash = *list;
      *list = (*list)->next;
      delete trash;
      return temp;
    }
    else
    {
        return 0;
    }
}

int tail_return (node_ll** list)
{
    if (*list != NULL)
    {
      if ((*list)->next == NULL)
        {
            return head_return(list);
        }
        else
        {
      node_ll* trash;
            for (trash = *list; trash->next->next; trash = trash->next);
            int temp = trash->next->payload;
            delete trash->next;
            trash->next = NULL;
            return temp;
        }
    }
    else
    {
        return 0;
    }
}

void find_remove (node_ll** list, int pload)
{
    if (*list != NULL)
    {
        node_ll* temp;//Declared before loop for use after loop.
        for (temp = *list; temp->next; temp = temp->next)
        {
            if (temp->payload == pload)
            {
                int trash = head_return(&temp);
            }
        }
        if (temp->payload == pload)
        {
            int trash = tail_return(list);
        }
    }
}

void print_ll (node_ll** list)
{
  node_ll* temp = *list;//Let temp be the address of the node that is the head of the list.
    while(temp)// != NULL
    {
        cout << temp->payload << endl;//Print out payload of the struct whose address is temp.
        temp = temp->next;//Set the address of temp equal to the address stored in next of the struct whose address is temp.
    }
}

int main()
{
    node_ll *blist = NULL;
    tail_insert(&blist, 2);
    tail_insert(&blist, 4);
    tail_insert(&blist, 6);
    find_remove(&blist, 4);
    print_ll(&blist);
    cout << '\n';

    system("PAUSE");
    return 0;
}

編集

これがあなたのコードを書き直す私の試みです。

void find_remove (node_ll** list, int pload)
{
    if (*list != NULL)
    {
        while (*list && (*list)->payload == pload)
        {
            head_return(list);
        }
        if (*list != NULL)
        {
            node_ll* temp;
            for (temp = *list; temp->next->next; temp = temp->next)
            {
                if (temp->next->payload == pload)
                {
                    node_ll* trash = temp->next;
                    temp->next = temp->next->next;
                    head_return(&trash);
                }
            }
        }
    }
}

編集2: ありがとう!この新しいソリューションは、最初に複数の一致ノード、中間に複数の一致ノード、または最後に複数の一致ノードがある場合に機能します。

void find_remove (node_ll** list, int pload)
{
    if (*list != NULL)
    {
        while (*list && (*list)->payload == pload)
        {
            head_return(list);
        }
        if (*list != NULL)
        {
            node_ll* temp;
            for (temp = *list; temp->next; temp = temp->next)
            {
                while (temp->next->next != NULL && temp->next->payload == pload)
                {
                    node_ll* trash = temp->next;
                    temp->next = temp->next->next;
                    head_return(&trash);
                }
            }
            if (temp->next == NULL && temp->payload == pload)
            {
                tail_return(list);
            }
        }
    }
}
4

1 に答える 1

1

クラッシュは、ループ ロジックが正しくないという事実によるものです。また、リンクされたリストを正しくリセットしていないことを意味する前のノードを追跡していないという事実が原因です。これは最も簡単な修正です。

void find_remove (node_ll** list, int pload)
{
    if (*list != NULL)
    {
        node_ll* temp, *prev=NULL;//Declared before loop for use after loop.
        for (temp = *list; temp != NULL; temp = temp->next)
        {
            if (temp->payload == pload)
            {
               if( NULL != prev )
               {
                  prev->next = temp->next ;
               }
                int trash = head_return(&temp);
            }

            prev=temp ;
         }
   }
}

正直なところ、コードには多くのスタイルの問題があり、C++ スタイルのコードよりも C スタイルのコードに似ています。Code Reviewを確認することを検討してください。

アップデート:

変更したコードでこれを変更すると、次のように機能します。

for (temp = *list; temp->next != NULL; temp = temp->next)
                   ^^^^^^^^^^^^^^^^^^

temp->nextループの先頭では、が NULLかどうかわからないため、これを行うことtemp->next->nextは決して有効ではありません。

于 2013-04-12T01:35:36.637 に答える