Ich arbeite durch die Übungen im Kapitel "Zeiger" von "Programmierung in C" von Kochan.Doppelt verbundene Liste. Code funktioniert ... sollte es? Viel weniger Code als andere Lösung
Ich habe ein Programm geschrieben, das eine doppelt verknüpfte Liste erstellt. Es druckt zuerst die Werte. Dann ruft er eine Funktion zum Entfernen eines Eintrags auf. Die Werte werden erneut gedruckt.
Schließlich wird eine zusätzliche Funktion aufgerufen, um einen Eintrag hinzuzufügen, gefolgt von einem erneuten Ausdruck.
Momentan funktioniert mein Code. Sie können es hier sehen:
#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;
}
JEDOCH einmal getan, ich wollte sehen, um zu überprüfen, ob andere Lösungen im Internet veröffentlicht worden waren, nur für den Fall, dass ich irgendetwas fehlte.
Nun, ich habe eine Frage und Antwort HERE gefunden und es gibt erhebliche Unterschiede.
Wenn Sie den Unterschied im Format, wie die Werte gedruckt werden, ignorieren, können Sie sehen, dass wesentlich mehr Code geschrieben wird, besonders in den Funktionen. Dies ist meine Funktion remove wieder:
void removeEntry(struct entry *start)
{
start->previous->next = start->next;
}
und das ist sie:
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;
}
Jetzt kann ich sehen, dass es eine Prüfung auf NULL ist, aber abgesehen davon, dass sie arbeiten sowohl mit Previous
und Next
Werte und haben eine if-Anweisung für jeden.
Ebenso können Sie meine insert
Funktion hier sehen:
void insertEntry(struct entry *addOn, struct entry *element)
{
element->next = addOn;
addOn->value = 400;
addOn->next = (struct entry *) 0;
}
und ihre:
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;
}
Bitte in meinem Kopf behalten, dass mein Code tut genau das, was ich habe versucht, meine zu tun, gedruckt Ausgabe ist:
100
200
300
100
300
100
300
400
Können Sie bitte versuchen, mir dies zu erklären? Ich fühle mich wie ein Idiot, weil ich damit nicht umgehen kann.
Dies ist ihr vollständiger Code:
#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;
}
Vielen Dank für Ihre Zeit.
Zu Beginn haben Sie ein '* vorheriges' Mitglied in Ihrem Knoten, aber Sie verwenden es nie. Ihr Code implementiert keine doppelt verkettete Liste ... –
Bereits beantwortet, aber nicht in der Lage zu sein, "waffle deinen Kopf drumherum" - hol ein wenig Papier und einen Bleistift und spiele ein wenig Computer: Arbeite durch den Code bis Du verstehst es. Den vorhandenen Code zu verdauen, ist eine ziemlich wichtige Fähigkeit. –
Was würde passieren, wenn Ihr Code versuchen würde, removeEntry mit n1 zu verwenden, in diesem Fall sollte n1-> previous auf list_pointer zeigen, aber list_pointer hat keinen nächsten Zeiger. Für einen removeEntry (& n1) sollte list_pointer aktualisiert werden, um auf n2 zu zeigen, und n2-> previous sollte auf null gesetzt werden. – rcgldr