在错误条目上运行的链接列表函数中删除条目和插入条目
Remove entry and Insert Entry in Linked Lists functions operating on the wrong entries
下午好。我正在从 Stephen G. Kochan 的一本名为 Programming in C Third Edition 的书中学习 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: %i\n", 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
函数有几个问题。
首先,您需要传入指向、InsertPosition
和EntryToInsert
的指针。这样做的原因是因为在 C 中,一切都是按值传递。这意味着当您将值传递给函数时,该函数将看到该值的 copy,而不是原始值。一旦该功能完成 - 副本将永远消失。所以如果你想修改函数内部的某些东西,并且在函数完成后让修改可见,你必须传递一个指向那个东西的指针。 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
函数的任何问题 - 同样,我认为没有问题。
代码中有几个问题。
将 InsertEntry 和 RemoveEntry 的声明移到 main() 之前。
初始化Previous字段时,列表头需要Previous = NULL。
打印列表时,需要避免分别打印出列表头和尾的Previous->Value和Next->Value。
在 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;
}
下午好。我正在从 Stephen G. Kochan 的一本名为 Programming in C Third Edition 的书中学习 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: %i\n", 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
函数有几个问题。
首先,您需要传入指向、InsertPosition
和EntryToInsert
的指针。这样做的原因是因为在 C 中,一切都是按值传递。这意味着当您将值传递给函数时,该函数将看到该值的 copy,而不是原始值。一旦该功能完成 - 副本将永远消失。所以如果你想修改函数内部的某些东西,并且在函数完成后让修改可见,你必须传递一个指向那个东西的指针。 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
函数的任何问题 - 同样,我认为没有问题。
代码中有几个问题。
将 InsertEntry 和 RemoveEntry 的声明移到 main() 之前。
初始化Previous字段时,列表头需要Previous = NULL。
打印列表时,需要避免分别打印出列表头和尾的Previous->Value和Next->Value。
在 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;
}