我正在通过指针' '用C'编程作者:Kochan。
我编写了一个创建双链表的程序。它首先打印值。然后它继续调用函数来删除条目。这些值会再次打印出来。
最后,调用一个附加函数来添加一个条目,然后再次打印。
现在,我的代码有效。你可以在这里看到它:
#include <stdio.h>
struct entry
{
int value;
struct entry *next;
struct entry *previous;
};
void removeEntry(struct entry *start);
void insertEntry(struct entry *addOn, struct entry *element);
int main (void)
{
//declarations
struct entry n1, n2, n3, addOn;
struct entry *list_pointer = &n1;
//creates list values and links
n1.value = 100;
n1.next = &n2;
n1.previous = list_pointer;
n2.value = 200;
n2.next = &n3;
n2.previous = &n1;
n3.value = 300;
n3.next = (struct entry *) 0;
n3.previous = &n2;
//prints out all list values
while(list_pointer != (struct entry *) 0)
{
printf("%i\n", list_pointer->value);
list_pointer = list_pointer->next;
}
printf("\n");
//resets list_pointer back to start
list_pointer = &n1;
//calls function and removes n2 from list by directly linking n1 to n3
removeEntry(&n2);
//print out amended list
while(list_pointer != (struct entry *) 0)
{
printf("%i\n", list_pointer->value);
list_pointer = list_pointer->next;
}
printf("\n");
list_pointer = &n1;
insertEntry(&addOn, &n3);
//print out amended list
while(list_pointer != (struct entry *) 0)
{
printf("%i\n", list_pointer->value);
list_pointer = list_pointer->next;
}
return 0;
}
void removeEntry(struct entry *start)
{
start->previous->next = start->next;
}
void insertEntry(struct entry *addOn, struct entry *element)
{
element->next = addOn;
addOn->value = 400;
addOn->next = (struct entry *) 0;
}
然而,一旦完成,我想检查是否有任何其他解决方案已在网上发布,以防我遗漏任何事情。
我找到了问题和回答HERE,并且存在很大的差异。
忽略值的打印格式的差异,您可以看到编写的代码要多得多,特别是在函数中。这是我的删除功能:
void removeEntry(struct entry *start)
{
start->previous->next = start->next;
}
这是他们的:
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;
}
现在我可以看到有一个NULL检查,但除此之外,他们正在处理Previous
和Next
值,并为每个值都有一个if语句。
同样,您可以在此处查看我的insert
功能:
void insertEntry(struct entry *addOn, struct entry *element)
{
element->next = addOn;
addOn->value = 400;
addOn->next = (struct entry *) 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;
}
请记住,我的代码完全符合我的目的,我的打印输出是:
100
200
300
100
300
100
300
400
你可以试着向我解释一下吗?我觉得自己像个白痴,因为我无法理解这一点。
这是他们的完整代码:
#include <stdio.h>vv
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;
}
感谢您的时间。
答案 0 :(得分:2)
代码不同,因为您的代码未成功实现双链表。例如,尝试在列表中间插入一个条目,然后从结尾打印到开头,你会发现链接的代码可以正常工作,但是你的链接代码没有。
答案 1 :(得分:2)
请记住,我的代码完全符合我的目的,我的打印输出是:....
这是新程序员所说的最强危险和天真的最重要的事情。它绝对没有告诉我们。编程不是最终证明手段合理性的问题。你可以在计算器上按错按钮,得到正确的答案吗?
您的测试包括在列表中单向遍历。单链表将通过该测试。
您是否测试了反向遍历?这是单链表和双链表之间的所有关键区别 你是否测试过中间和前后的插入和移除?
周期怎么样?如果您将一个元素添加到列表中已经存在的列表中会发生什么?