Wie kann ich die Aufgabe mit verketteten Listen lösen?

  • C

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von a.b_om.

    Wie kann ich die Aufgabe mit verketteten Listen lösen?

    Liebe Community,

    Ich habe eine Aufgabe bekommen, indem man mit doppelt verketteten Listen in C arbeiten muss.

    Leider komme ich nicht mehr weiter. Was muss ich jetzt machen?

    Aufgabenstellung:
    • keine C++ Befehle
    • keine externe Bibliotheken
    • keine globale Variablen
    • Listenaufbau ist egal( Auto, Yugiohkarten, Flugzeuge, Fahrräder, Bücher, ...)
    • Char-Arrays mit Anfangsbuchstaben zu befüllen
    • Zahlen sind randomised
    • Funktionalität
      • Liste erstellen, man kann die Anzahl der gewünschten Elemente eingeben
      • Ein gewünschtes Element löschen. Wird durch mehrere Eingaben bestimmt
      • Liste sortieren (ASC oder DESC)
      • Liste löschen
      • Liste ausgeben
      • Programm beenden
    • Main-Funktion
      • textbasierten einfachen Menu
      • für jede Aufgabe wird eine Methode aufgerufen
    Mein bis jetziger Code:
    Spoiler anzeigen

    C-Quellcode

    1. #include "pch.h"
    2. #include <iostream>
    3. #include <stdio.h>
    4. #include "LinkedList.h"
    5. #define MAX 265
    6. int main()
    7. {
    8. do
    9. {
    10. printf("Moechten Sie ein Deck erstellen(Deec), ein Deck loeschen(Delo), Karte aus dem Deck loeschen(Kadelo), ein Deck ausgeben(Deau) oder das Programm schliessen(Prsc)\n");
    11. char antwort[MAX];
    12. fgets(antwort, MAX, stdin);
    13. if (antwort[0] == 'D' && antwort[1] == 'e' && antwort[2] == 'e' && antwort[3] == 'c') {
    14. DeckErstellen();
    15. }
    16. if (antwort[0] == 'D' && antwort[1] == 'e' && antwort[2] == 'l' && antwort[3] == 'o') {
    17. DeckLoeschen();
    18. }
    19. if (antwort[0] == 'K' && antwort[1] == 'a' && antwort[2] == 'd' && antwort[3] == 'e' && antwort[4] == 'l' && antwort[5] == 'o') {
    20. KarteAusDeckLoeschen();
    21. }
    22. if (antwort[0] == 'D' && antwort[1] == 'e' && antwort[2] == 'a' && antwort[3] == 'u') {
    23. DeckAusgeben();
    24. }
    25. if (antwort[0] == 'P' && antwort[1] == 'r' && antwort[2] == 's' && antwort[3] == 'c') {
    26. return 0;
    27. }
    28. if (antwort != "Deec" || antwort != "Delo" || antwort != "Kadelo" || antwort != "Deau" || antwort != "Prsc") {
    29. printf("Bitte geben Sie eine Abkürzung ein!");
    30. }
    31. } while (true);
    32. }
    33. void DeckErstellen() {
    34. }
    35. void DeckLoeschen() {
    36. }
    37. void KarteAusDeckLoeschen() {
    38. }
    39. void DeckAusgeben() {
    40. }
    41. void ProgrammSchliessen() {
    42. }
    43. typedef struct YugiohKarte {
    44. char Name[100];
    45. char Kartenart[20];
    46. int Stufe;
    47. int Rang;
    48. int Pendelstufe;
    49. int Link;
    50. char ATK[20];
    51. char DEF[20];
    52. char Eigenschaft[20];
    53. char Monstertyp[40];
    54. char Kartentyp[30];
    55. char Beschreibung[500];
    56. struct YugiohKarte* pNext;
    57. struct YugiohKarte* pPrev;
    58. } struYugiohKarte;

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „a.b_om“ ()

    Wenn du schon zu faul bist, deine Hausaufgaben selbständig zu erledigen, könntest du wenigsten KONKRETE Fragen stelllen !
    Echt unverschähmt, diese Vorgehensweise ! :thumbdown:

    R.I.P. Bildungssystem ! :(
    Ok, dann biste eben nicht faul (scheint aber so), dennoch bleibt meine eigentliche Kritik bestehen !
    Also nochmal: Könntest du wenigsten KONKRETE Fragen stelllen !
    Also das Vergleichen der einzelnen Chars ist ziemlich unschön. Nutze doch lieber strcmp.
    Und wo genau hängst Du jetzt? Versuche Dir zu überlegen, was Du genau tun musst und versuche das dann in Code umzusetzen. Wo willst Du dann überhaupt das Deck speichern? Weil globale Variablen dürft Ihr ja nicht benutzen. Also gehe ich davon aus, dass das Array (Kartendeck) in der Schleife erstellt wird und Du mit Parametern und Rückgabetypen für die jeweiligen Funktionen arbeiten musst. Spätestens da brauchst Du allerdings Pointer, weil wenn Du das Deck in der Methode erstellst, landet es sonst auf dem Stack und ist danach wieder weg..

    Edit: Eine doppelt verkettete Liste ist quasi auch nur eine Struktur, die wiederum Items enthält, die jeweils zwei Pointer auf Elemente rekursiv enthält (das vorherige und das nächste).

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Ja, wie beschrieben.

    C-Quellcode

    1. typedef struct ylist_el {
    2. ylist_el* vorherige,
    3. ylist_el* nächste,
    4. YugiohKarte* karte
    5. } YugiohListenElement;


    Das ist Deine Struktur für die Liste. Somit kannst Du sie aufbauen. Das erste Element hat dann kein vorheriges (NULL) und dann nur ein nächstes und so musst Du die nacheinander setzen und anfügen.Für das erste Element wirst Du halt dann Speicher alloziieren müssen in Deiner Erstell-Methode. Das heißt: free nicht vergessen!

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Das ist das delete-Pendant in C, siehe z.B. hier. Da es bei C und C++ keinen Garbage Collector gibt, muss man sich immer schön selber um die Speicherfreigabe von Objekten kümmern, sonst bleiben die im Speicher, wenn das Programm beendet wird und sind nicht mehr erreichbar. Das gibt sog. memory leaks.
    C: Anlage neuer Objekte mit malloc, Freigabe mit free
    C++: Anlage neuer Objekte mit new, Freigabe mit delete bzw. delete[] (bei Arrays)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed und @Trade
    Aber wie mache ich das, wenn ich ein Deck(Liste von Yugiohkarten) erstellen möchte, die eine unbestimmte Anzahl Elemente hat?
    Also ich dachte an die Struktur:
    Yugiohkarte (Eine einzelne Karte)
    Deck (unbestimmte Anzahl Yugiohkarten)
    Deckliste (Alle Decks, die erfasst wurden.)


    Wie kann ich einem den vorherigen bzw. nächsten Eintrag speichern?
    ? Für den Fall, dass das noch nicht klar sein sollte: Eine Linked List geht so: Du hast eine Yugioh-Karte mit all ihren Beschreibungen. Deren Adresse (Pointer) merkst Du Dir. Sie ist der Anfang der Liste. Und sie verweist per Pointer auf die nächste Karte. Da es nur die eine Karte gibt, verweist der nächste-Karte-Pointer auf null. Dann erzeugst Du eine nächste Karte. Die steht quasi wie die erste Karte irgendwo im Speicher. Und nun verknüpfst Du die beiden miteinander, indem Du entweder sagst, dass die 1. Karte auf die 2. verweist, oder die 2. auf die 1. Und so weiter. Dann hast Du also den allgemein bekannten / globalen Startpointer, der auf die 1. Karte vwerweist, die 1. Karte verweist auf die 2., die 2. auf die 3., ... und die z.B. 24. verweist auf null. Dann weist Dein Programm: Ok, es gibt keine weitere Karte.
    Bei einer double linked list ist es eben so, dass Karte 1 auf Karte 2 verweist und Karte 2 auf Karte 1. Macht das hin- und herwechseln zwischen den Karten einfacher.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed
    Das habe ich verstanden, aber wie mache ich das mit den Verweisen.

    Edit:
    Und wie mache ich das mit dem Anzeigen?
    Schreiben weiss ich, aber wie bekomme ich die einzelnen Listen?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „a.b_om“ ()

    Oh, ich seh gerade, dass ich mit meiner Beschreibung Trade und Post#8 reingrätsche. Nuja. Er kann sich ja dann auch nochmal äußern.
    C++ ist bei mir zwar 15 Jahre her und mit C hab ich mich nur sehr kurz beschäftigt, aber grundsätzlich sollte es so laufen:
    Sobald Du eine Karte erstellt hast, nimmst Du dessen Pointer und speicherst ihn in der Variable, die auf die letzte Karte verweist (Achtung: normale linked list):

    C-Quellcode

    1. YugiohKarte* AddressOfLatestCard = null;
    2. //...
    3. DieErsteKarteDieDuErstelltHast.pPrev = AddressOfLatestCard;
    4. AddressOfLatestCard = &DieErsteKarteDieDuErstelltHast;

    Wenn Du dann eine weitere Karte erstellt hast:

    C-Quellcode

    1. DieZweiteKarteDieDuErstelltHast.pPrev = AddressOfLatestCard;
    2. AddressOfLatestCard = &DieErsteKarteDieDuErstelltHast;

    Natürlich so, dass das ganze redundanzfrei ist.

    ##########

    das Anzeigen: was Du jetzt mit schreiben meinst, weiß ich nicht, aber geht es Dir beim Anzeigen darum, wie Du durch die Karten durchgehst? Du fängst bei AddressOfLatestCard an und schaust, ob der Adressinhalt, umgewandelt in eine Karte, bei pPrev auf null verweist. Wenn nicht, nimmst Du die Adresse her und wandelst die wiederum in eine Karte um. Also ungefähr so:

    C-Quellcode

    1. void* AddressOfCurrentCard = AddressOfLatestCard;
    2. while (AddressOfCurrentCard != null)
    3. {
    4. cout << (*AddressOfLatestCard).Stufe << endl;
    5. AddressOfCurrentCard = AddressOfCurrentCard -> pPrev;
    6. }

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    @VaporiZed
    Sorry, hab es nicht genug erklärt, was ich da meinte. Zu den Menupunkte die ich bis jetzt habe, werden weitere dazukommen.
    ein Beispiel meines Problems:
    Benutzer möchte eine neue Karte erstellen.
    Er geht zum Menupunkt (Neue Karte erstellen) und gibt alle Werte an. Danach, wird er gefragt, ob er eine weitere Karte machen möchte oder nicht. Falls er nein sagt, geht es zurück zum Hauptmenu. Danach, wenn er wieder eine Karte erstellen möchte, geht er wieder dorthin. Wie bekomme ich die ganze Verweisung hin, wenn ich nicht die Karten nacheinander erstelle.

    Edit:
    Ohne Globale Variablen.

    Edit 2:
    Ich habe jetzt erst den Umfang des Projektes begriffen, es würde auch nur mit Yugiohkartenstruktur gehen ohne Deck oder etwas ähnliches. Meine Frage bleibt dennoch bestehen, ich baue nur das Programm kurz um. Ich brauche keinen Deck und Deckliste mehr. Alles soll jetzt auf die Yugiohkartenstruktur bestehen.
    Ja gut, dafür braucht es keine globale Variable, da kannst Du auch ne lokale Variable zum Anfang von Main erstellen/deklarieren und die dann an die anderen Prozeduren weitergeben. Und das mit dem Abbrechen und später weiterführen/Karten ergänzen: Sobald Du 5 Karten nacheinander erstellt hast, verweist ja die AddressOfLatestCard auf die zuletzt erstellte Karte. Dann gehst Du eben mit der o.g. Schleife dorthin, wo pPrev auf null verweist und setzt dort die nächste Karteninstanz hin. Oder ich versteh es wieder falsch. Dann brauche ich eine Umschreibung des von Dir verwendeten Begriffs »Verweisung«. Damit kann ich nix anfangen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hier gibt es ein kleines Tutorial, die die wichtigsten Sachen zeigen. Auch die doppelt verkettete Liste ist darunter.
    Vielleicht einfach mal durcharbeiten.

    openbook.rheinwerk-verlag.de/c…n_datenstrukturen_001.htm
    perlgeek.de/de/artikel/doppelt-verkettete-listen

    Freundliche Grüsse

    exc-jdbi
    @exc-jdbi
    Danke, ich bin gerade dran Werte in die StartKarte einzutragen, das funktionierte nicht wie in den Beispielen und es gab sonst ein IValue Exception.

    Wie kann ich das sonst machen?
    Meine jetztiger relevanter Code:
    Spoiler anzeigen

    C-Quellcode

    1. YugiohKarte YugiohKarteErstellen(YugiohKarte ersteYugiohKarte) {
    2. char antwort[MAX];
    3. int anzahlKarten;
    4. do
    5. {
    6. printf("\nWie viele Yugiohkarten moechten Sie erstellen? Bitte geben Sie nur Zahlen ein, sonst kommt es zu einem Absturz.");
    7. fgets(antwort, MAX, stdin);
    8. anzahlKarten = *antwort;
    9. for (int i = 0; i <= anzahlKarten; i++)
    10. {
    11. if (ersteYugiohKarte.Beschreibung[0] == 'D' && ersteYugiohKarte.Beschreibung[1] == 'a' &&ersteYugiohKarte.Beschreibung[2] == 's' &&ersteYugiohKarte.Beschreibung[3] == ' ' &&ersteYugiohKarte.Beschreibung[4] == 'i' &&ersteYugiohKarte.Beschreibung[5] == 's' &&ersteYugiohKarte.Beschreibung[6] == 't' &&ersteYugiohKarte.Beschreibung[7] == ' ' &&ersteYugiohKarte.Beschreibung[8] == 'd' &&ersteYugiohKarte.Beschreibung[9] == 'i' &&ersteYugiohKarte.Beschreibung[10] == 'e' &&ersteYugiohKarte.Beschreibung[11] == ' ' &&ersteYugiohKarte.Beschreibung[12] == 'e' &&ersteYugiohKarte.Beschreibung[13] == 'r' &&ersteYugiohKarte.Beschreibung[14] == 's' &&ersteYugiohKarte.Beschreibung[15] == 't' &&ersteYugiohKarte.Beschreibung[16] == 'e' &&ersteYugiohKarte.Beschreibung[17] == ' ' &&ersteYugiohKarte.Beschreibung[18] == 'Y' &&ersteYugiohKarte.Beschreibung[19] == 'u' &&ersteYugiohKarte.Beschreibung[20] == 'g' &&ersteYugiohKarte.Beschreibung[21] == 'i' &&ersteYugiohKarte.Beschreibung[22] == 'o' &&ersteYugiohKarte.Beschreibung[23] == 'h' &&ersteYugiohKarte.Beschreibung[24] == 'K' &&ersteYugiohKarte.Beschreibung[25] == 'a' &&ersteYugiohKarte.Beschreibung[26] == 'r' &&ersteYugiohKarte.Beschreibung[27] == 't' &&ersteYugiohKarte.Beschreibung[28] == 'e' &&ersteYugiohKarte.Beschreibung[29] == '.')
    12. {
    13. //Hier wird zugewiesen
    14. }
    15. }
    16. } while (true);
    17. }
    18. int main()
    19. {
    20. do
    21. {
    22. struct YugiohKarte ersteYugiohKarte = {"Name", "Kartenart", 1, 0, 0, 0, "ATK", "DEF", "Eigenschaft", "Monstertyp", "Kartentyp", "Das ist die erste YugiohKarte."};
    23. printf("Moechten Sie eine Yugioh-Karten erstellen(YKE), eine Yugioh-Karte loeschen(YKL), eine Yugioh-Karte ausgeben(YKA) oder das Programm schliessen(Prsc):");
    24. char antwort[MAX];
    25. fgets(antwort, MAX, stdin);
    26. if (antwort[0] == 'Y' && antwort[1] == 'K' && antwort[2] == 'E') {
    27. ersteYugiohKarte = YugiohKarteErstellen(ersteYugiohKarte);
    28. }
    29. else if (antwort[0] == 'Y' && antwort[1] == 'K' && antwort[2] == 'L') {
    30. YugiohKarteLoeschen(ersteYugiohKarte);
    31. }
    32. else if (antwort[0] == 'Y' && antwort[1] == 'K' && antwort[2] == 'A') {
    33. YugiohKarteAusgeben(ersteYugiohKarte);
    34. }
    35. else if (antwort[0] == 'P' && antwort[1] == 'r' && antwort[2] == 's' && antwort[3] == 'c') {
    36. return 0;
    37. }
    38. else
    39. {
    40. printf("Bitte geben Sie eine Abkuerzung ein!");
    41. }
    42. } while (true);
    43. }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „a.b_om“ ()