c-删除条目和在链表中插入条目功能对错误条目进行操作



下午好。我从StephenG.Kochan的一本名为《用C编程第三版》的书中学习C语言。我写了一些代码,应该从列表中插入和删除某些条目,但它确实做到了,问题是,它没有删除正确的条目,也没有完全将条目插入正确的位置。代码如下。如有任何帮助,我们将不胜感激!

//Insert and Remove entry functions using doubly linked lists
#include <stdio.h>
struct Entry
{
    int Value;
    struct Entry *Previous;
    struct Entry *Next;
};

int main()
{
    void InsertEntry (struct Entry *InsertPosition, struct Entry EntryToInsert);
    void RemoveEntry (struct Entry *EntryToRemove);
    struct Entry N1, N2, N3, N4, N5, Insert, *Start = &N1;
//set initial values
    N1.Value = 10;
    N2.Value = 20;
    N3.Value = 20;
    N4.Value = 30;
    N5.Value = 40;
    Insert.Value = 35;
//link the list
    N1.Next = &N2;
    N2.Next = &N3;
    N3.Next = &N4;
    N4.Next = &N5;
    N5.Next = (struct Entry *) 0;
//Link again
    N1.Previous = &N1;
    N2.Previous = &N1;
    N3.Previous = &N2;
    N4.Previous = &N3;
    N5.Previous = &N4;
    InsertEntry(&N4, Insert);
    RemoveEntry(&N2);
//Display the Lists
    while (Start->Next != (struct Entry *) 0)
    {
        printf("Previous: %i, Current: %i, Next: %in",         Start->Previous->Value, Start->Value, Start->Next->Value);
        Start = Start->Next;
    }
    return 0;
}
void InsertEntry (struct Entry *InsertPosition, struct Entry EntryToInsert)
{
    EntryToInsert.Previous = InsertPosition->Previous;
    EntryToInsert.Next = InsertPosition;
    InsertPosition->Previous->Next = &EntryToInsert;
}
void RemoveEntry (struct Entry *EntryToRemove)
{
    EntryToRemove->Previous->Next = EntryToRemove->Next;
}

代码中有几个问题。

将InsertEntry和RemoveEntry的声明移到main()之前。

初始化Previous字段时,列表头需要Previous=NULL。

当打印出列表时,需要避免分别打印出列表头和尾部的"上一个->值"one_answers"下一个->值"。

在InsertEntry()函数中,代码通过将副本插入列表的值传递EntryToInsert结构。我猜您打算通过指针将原始结构插入列表。

在InsertEntry()函数中,还需要设置InsertPosition->Next->Previous。

在InsertEntry()函数中,在设置InsertPosition->Previous->Next和InsertPosition->Next->Previous之前,需要检查您是否分别位于列表的开头和末尾。

在RemoveEntry()函数中,还需要设置EntryToRemove->Next->Previous。

在RemoveEntry()函数中,在设置EntryToRemove->Previous->Next和EntryToRemove->Next->Previous之前,需要分别检查您是否位于列表的开头和末尾。

在RemoveEntry()函数中,还需要设置EntryToRemove->Previous=NULL和EntryToRemove->Next=NULL。

我建议你尝试自己解决上述每一个问题。如果你在修复给定问题时遇到问题,我已经将完整的代码与我建议的修复程序一起提供给你看。

struct Entry
{
    int Value;
    struct Entry *Previous;
    struct Entry *Next;
};
void InsertEntry(struct Entry *InsertPosition, struct Entry *EntryToInsert);
void RemoveEntry(struct Entry *EntryToRemove);
int main()
{
    struct Entry N1, N2, N3, N4, N5, Insert, *Start = &N1;
    //set initial values
    N1.Value = 10;
    N2.Value = 20;
    N3.Value = 20;
    N4.Value = 30;
    N5.Value = 40;
    Insert.Value = 35;
    //link the list
    N1.Next = &N2;
    N2.Next = &N3;
    N3.Next = &N4;
    N4.Next = &N5;
    N5.Next = NULL;
    //Link again
    N1.Previous = NULL;
    N2.Previous = &N1;
    N3.Previous = &N2;
    N4.Previous = &N3;
    N5.Previous = &N4;
    InsertEntry(&N4, &Insert);
    RemoveEntry(&N2);
    //Display the Lists
    while (Start != (struct Entry *) 0)
    {
        printf("Previous: ");
        if (Start->Previous != NULL)
        {
            printf("%i", Start->Previous->Value);
        }
        else
        {
            printf("NULL");
        }
        printf(", Current: %i, Next: ", Start->Value);
        if (Start->Next != NULL)
        {
            printf("%i", Start->Next->Value);
        }
        else
        {
            printf("NULL");
        }
        printf("n");
        Start = Start->Next;
    }
    return 0;
}
void InsertEntry(struct Entry *InsertPosition, struct Entry *EntryToInsert)
{
    EntryToInsert->Previous = InsertPosition->Previous;
    EntryToInsert->Next = InsertPosition;
    if (InsertPosition->Previous != NULL)
    {
        InsertPosition->Previous->Next = EntryToInsert;
    }
    InsertPosition->Previous = EntryToInsert;
}
void RemoveEntry(struct Entry *EntryToRemove)
{
    if (EntryToRemove->Previous != NULL)
    {
        EntryToRemove->Previous->Next = EntryToRemove->Next;
    }
    if (EntryToRemove->Next != NULL)
    {
        EntryToRemove->Next->Previous = EntryToRemove->Previous;
    }
    EntryToRemove->Previous = NULL;
    EntryToRemove->Next = NULL;
}

InsertEntry函数有几个问题。

首先,您需要将指针传递给InsertPositionEntryToInsert。这是因为在C中,所有东西都是通过值传递的。这意味着,当您将值传递给函数时,该函数将看到该值的副本,而不是原始值。一旦该功能完成,副本将永远消失。因此,如果你想修改函数内部的某些内容,并在函数完成后使其可见,那么你必须传递一个指向该内容的指针。C中的指针指向内存中的某个位置,因此即使函数获得了该指针的副本,它指向的位置也是相同的。

这意味着第一步是将函数定义为:

void InsertEntry (struct Entry *InsertPosition*, struct Entry *EntryToInsert)

其次,插入EntryToInsert的顺序与您想要完成的任务不符-您希望在InsertPosition之后而不是之前插入此值

void InsertEntry (struct Entry *InsertPosition, struct Entry *EntryToInsert)
{
    //Goal is to insert EntryToInsert *before* InsertPosition
    //  so that it will look like:
    //  ??? --> EntryToInsert --> InsertPosition
    //Step 1: ??? <-- EntryToInsert
    EntryToInsert->Prev = InsertPosition->Prev;
    //Step 2: EntryToInsert --> InsertPosition
    EntryToInsert->Next = InsertPosition;
    //Step 3: ??? --> EntryToInsert
    EntryToInsert->Prev->Next = EntryToInsert;
    //Step 4: EntryToInsert <-- InsertPosition
    InsertPosition->Prev = EntryToInsert;
}

最后,您当前在main函数内部的函数声明通常在函数外部(之前)。

解决这个问题应该可以解决RemoveEntry函数的任何问题——再说一遍,我认为这没有问题。

相关内容

  • 没有找到相关文章

最新更新