home *** CD-ROM | disk | FTP | other *** search
- #pragma +
- /*
- Doppelt verkettete Listen
-
- Ein kleines Beispiel für dynamische Datenstrukturen in C++,
- aber ohne objektorientierte Programmierung
-
- Verbrochen von Jens Gelhar am 13.01.92
- */
-
-
- #include <stream.h>
- #include <string.h>
-
-
- // * * * Datentypen * * *
-
- struct Eintrag // ein einzelner "Telefonbuch"-Eintrag
- {
- Eintrag *next, *prev; // Vorgänger und Nachfolger
-
- char name[30]; // Name und...
- char nummer[20]; // Telefonnummer
- };
-
-
- struct Liste // sortierte Liste von Einträgen
- {
- Eintrag *anfang, *ende; // erstes bzw. letztes Listenelement
- };
-
-
- // * * * Funktionen * * *
-
- void Init(Liste &L)
- // Initialisiert eine Listenstruktur, indem sie ihre beiden
- // Pointer auf 0 setzt:
- { L.anfang = 0;
- L.ende = 0;
- }
-
-
- void Ausgabe (const Liste &L)
- // Telefonbuch ausgeben
- {
- for(Eintrag *E = L.anfang; E; E = E->next)
- cout << E->name << ": " << E->nummer << "\n";
- }
-
-
- Eintrag *Einfueg(Liste &L, const char Name[], const char Nummer[])
- // fügt einen neuen Eintrag in die Liste ein
- {
- // neues Element erzeugen:
- Eintrag *neu = new Eintrag;
-
- if (!neu) return 0; // kein Speicher frei!
-
- // neues Element initialisieren:
- strcpy(neu->name, Name);
- strcpy(neu->nummer, Nummer);
-
- // Richtige Position zun Einfügen suchen:
- Eintrag *pos = L.anfang;
-
- while (pos!=0 && strcmp(pos->name, Name) < 0)
- pos = pos->next;
-
- // Element in Liste einhängen, dabei diverse Sonderfälle beachten:
-
- if (pos == 0)
- // Sonderfall: Anfügen an das Ende der Liste
- {
- Eintrag *alt = L.ende; // altes Listenende
-
- if (alt != 0)
- // allgemeiner Unter-Fall: wirklich anhängen
- {
- alt->next = neu;
- neu->prev = alt;
- neu->next = 0;
- L.ende = neu;
- }
- else
- // spezieller Spezialfall: Liste ist noch leer
- { neu->next = 0;
- neu->prev = 0;
- L.anfang = neu;
- L.ende = neu;
- }
- }
- else
- if (pos->prev == 0)
- // Sonderfall: Neues Element an Listenanfang hängen
- {
- pos->prev = neu;
- neu->next = pos;
- neu->prev = 0;
- L.anfang = neu;
- }
- else
- // allgemeiner Fall: Element in Liste einhängen
- {
- Eintrag *vor = pos->prev;
- // "neu" zwischen "vor" und "pos" einhängen:
- vor->next = neu;
- neu->prev = vor;
- neu->next = pos;
- pos->prev = neu;
- }
-
- // Fertig, Zeiger auf neues Element zurückgeben:
- return neu;
-
- }
-
- void AllesLoeschen(Liste &L)
- // löscht sämtliche Listenelemente
- {
- Eintrag *p = L.anfang;
-
- while(p)
- { Eintrag *hilf = p;
- p=p->next;
- delete hilf;
- }
- Init(L);
- }
-
- void Loeschen(Liste &L, Eintrag *E)
- // Löscht das Element, auf das "E" zeigt, aus Liste "L"
- {
- // Vorgänger unf Nachfolger des zu löschenden Elements
- Eintrag *vor = E->prev, *nach = E->next;
-
- if (vor)
- // Element hat Vorgänger: Dann dessen Nachfolger umsetzen
- vor->next = nach;
- else
- // kein Vorgänger: Dann Listenanfang aktualisieren
- L.anfang = nach;
-
- if (nach)
- // Element hat Nachfolger: Dann dessen Vorgänger verändern
- nach->prev = vor;
- else
- // kein Nachfolger, also Listenende anpassen
- L.ende = vor;
-
- delete(E);
- }
-
-
- Eintrag *Suche(const Liste &L, char *Name)
- // Sucht einen Eintrag mit diesem Namen und gibt Zeiger auf das
- // zugehörige Listenelement zurück, oder 0 bei Fehler
- {
- for( Eintrag *p = L.anfang;
- p && strcmp(p->name, Name);
- p = p->next );
- return p;
- }
-
-
- // * * * Hauptprogram * * *
-
- void main()
- {
- // Eine Liste wird deklariert und initialisiert:
-
- Liste l;
- Init(l);
-
- // Ein paar Beispieldaten werden eingefügt:
-
- Einfueg(l, "Harley-Davidson", "001-414/342-4680");
- Einfueg(l, "Boris Becker", "0815/4711");
- Einfueg(l, "James Bond", "007/26731");
- Einfueg(l, "Maxon", "06196/481813");
- Einfueg(l, "Zaphod Beeblebrox", "00042/08154242");
- Einfueg(l, "Luxemburg", "00352");
- Einfueg(l, "Queensr\0377che", "795069");
- Einfueg(l, "Fishbone", "4676152");
-
- // Einen Datensatz suchen und ggf. löschen:
-
- Eintrag *e = Suche(l,"Maxon");
- if (e)
- Loeschen(l, e);
- else
- cout << "Name nicht gefunden!\n";
-
- // restliche Liste ausgeben:
- Ausgabe(l);
-
- // ...und wieder aufräumen:
- AllesLoeschen(l);
-
- }
-