Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Doppelt verkettete Liste

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
17.08.2006, 15:36 Uhr
WindDancer1



Hi Leute ,

ich hab mich in letzter Zeit mit verketteten Listen Bäumen etc auseinandergesetzt.
Soweit funktioniert eigentlich alles .
Aber eine Frage hab ich, ich hab hier ein kleines Beispielprg. geschrieben, das soweit funktioniert.
Nur wenn ich in dem Teil *** Neues beliebiges Objekt einfügen ***
das erste cout ein- und das zweite cout auskommentiere bekomm ich die Fehlermeldungie Anweisung in XXX verweist auf den Speicher in XXX, der Vorgang read konnte nicht ausgeführt werden ... . :confused:
Ich müsste aber doch mit previous = prev genauso nach oben wie mit next nach unten duch die Liste gehen können.
Wisst ihr was ich falsch mach und vorallen wie es richtig geht ?
Hier mal mein code:

C/C++ Code:


Bearbeitung von 0xdeadbeef:

Im Interesse der Scrollbarkeit Code entfernt, in vermutetem Einklang mit dem Willen des Autors (siehe nächsten Beitrag).



vielen Dank schon mal für eure Mühe

ShadowEater

Dieser Post wurde am 17.08.2006 um 17:01 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
17.08.2006, 16:08 Uhr
WindDancer1



Sorry wegen dem Code Chaos hier der richtige:


C++:
#include<iostream>

using namespace std;

struct mvListe
{
    int data;
  
    mvListe *prev;
    mvListe *next;
};

mvListe *neu    = NULL;
mvListe *head    = NULL;
mvListe *current= NULL;

void showList(mvListe *head, char const headline[]);

void main()
{

    int i = 0;
    for (i = 0; i < 10 ; i++)
    {
        neu = new mvListe;
        neu->next = head;
        head = neu;
        neu->data = i;
    }
        showList(head,"Neue Liste");

      
  
//****************************** Neues erstes Objekt einfügen **********************************


        neu = new mvListe;
  
        neu->prev = head;
        neu->next = neu->prev;
        head = neu;

        neu->data = 1024;

        showList(head,"Neues erstes Element");

  
//****************************** Neues letztes Objekt einfügen ***********************************


        neu = new mvListe;
      
        current = head;

        while (current->next!= NULL)
        {
            current = current->next;
        }
         neu->prev = current;
        current->next = neu;
        neu->next = NULL;
      
        neu->data = 2048;

        showList(head,"Neues letztes Element");


//****************************** Neues beliebiges Objekt einfügen *********************************


        neu = new mvListe;
      
        int j = 0;
        int index = 5;
        current = head;

        while (j < index)
        {
            current = current->next;
            j++;
        }

        neu->next = current->next;
        current->next = neu;

        neu->prev = current;

        neu->data = 3072;

        showList(head,"Neues beliebiges Element");

      // cout << neu->prev->prev->prev->data << endl << endl; :confused:

      cout << neu->next->next->next->data << endl << endl;

}





void showList(mvListe *head, char const headline[])
{
    cout << headline << endl << endl;
    current = head;
    while (current != NULL)
    {
        cout << current->data << endl;
        current = current->next;
    }
    cout << endl << endl;
}


 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
17.08.2006, 17:08 Uhr
0xdeadbeef
Gott
(Operator)


Du solltest die prev-Pointer auch setzen, sonst zeigen die nachher ins Nirvana. Wie zum Beispiel verursacht durch das hier:

C++:
    for (i = 0; i < 10 ; i++)
    {
        neu = new mvListe;
        neu->next = head;
        head = neu;
        neu->data = i;
    }


Außerdem solltest du auch den Rest des Codes nochmal überprüfen, es scheint mir teilweise so, als zeige der prev-Zeiger nachher nicht zwingend auf das jeweils vorherige Element. Ich tu mich jetzt ein bisschen schwer mit Korrekturen, weil mir nicht ganz klar ist, wie du dir das designtechnisch vorgestellt hast - soll head->prev NULL oder head sein, solche Scherze.

Übrigens, kleiner Tip, das ganze geht deutlich einfacher, wenn du noch einen tail-Pointer einführst und head bzw. tail auf dummy-Elemente zeigen lässt. Ich schuster dafür grad mal kurz was zusammen, füge das dann nachher hier ein.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
17.08.2006, 17:28 Uhr
~Blubber2063
Gast


Ich mag mich irren, aber ich glaube du iterierst über die liste solange next != NULL aber du hast beim einfügen des Elements den next Zeiger nicht auf 0 initalisiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
17.08.2006, 17:43 Uhr
0xdeadbeef
Gott
(Operator)


So, hier dummy-liste zur Verdeutlichung. Die Implementierung eines geeigneten Interfaces bleibt dem Leser als Übungsaufgabe vorbehalten Das Prinzip sollte jedenfalls klar werden. Die Einfachheit dieses zunächst etwas unintuitiven Sonderfalls ergibt sich daraus, dass deutlich weniger Sonderfälle zu behandeln sind, da z.B. jedes Element immer einen Vorgänger und Nachfolger hat.

C++:
#include <iostream>

namespace my {
  struct list_element {
    int data;
    list_element *prev, *next;

    list_element(int x) : data(x) { }
  };

  class list {
  public:
    list() : head(new list_element(0)), tail(new list_element(0)), size_(0) {
      // Dummies initialisieren
      head->prev = tail->prev = head;
      head->next = tail->next = tail;
    }

    ~list() {
      list_element *ptr = head->next;
      do {
        delete ptr->prev;
        ptr = ptr->next;
      } while(ptr != tail);
      delete tail;
    }

    ::std::size_t size() const { return size_; }

    void push_front(int data) {
      insert_before(head->next, new list_element(data));
    }

    void push_back(int data) {
      insert_before(tail, new list_element(data));
    }

    void insert(int pos, int data) {
      insert_before(get_node(pos), new list_element(data));
    }

    int get_data(int pos) {
      return get_node(pos)->data;
    }

    void remove_front() {
      remove(head->next);
    }

    void remove_back() {
      remove(tail->prev);
    }

    void remove_position(int pos) {
      if(pos < size()) {
        remove(get_node(pos));
      } else
        throw pos;
    }

  private:
    void insert_before(list_element *anchor, list_element *new_element) {
      new_element->prev = anchor->prev;
      new_element->next = anchor;
      anchor->prev->next = anchor->prev = new_element;

      ++size_;
    }

    void remove(list_element *node) {
      node->prev->next = node->next;
      node->next->prev = node->prev;

      delete node;
      --size_;
    }

    list_element *get_node(::std::size_t pos) {
      list_element *ptr = head->next;

      for(int i = 0; i < pos; ++i)
        ptr = ptr->next;

      return ptr;
    }

    list_element *head, *tail;
    ::std::size_t size_;
  };
}


int main() {
  my::list ls;

  ls.push_front(10);
  ls.push_back(20);
  ls.push_front(5);
  ls.push_back(30);

  ls.insert(2, 12);
  ls.insert(3, 13);
  ls.insert(2, 11);

  for(int i = 0; i < ls.size(); ++i)
    std::cout << ls.get_data(i) << " ";
  std::cout << std::endl;

  ls.remove_front();
  ls.remove_back();
  ls.remove_position(2);
  ls.remove_position(3);

  for(int i = 0; i < ls.size(); ++i)
    std::cout << ls.get_data(i) << " ";
  std::cout << std::endl;
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
17.08.2006, 19:27 Uhr
WindDancer1



D*A*N*K*E 0xdeadbeef,

Du hast mich auf den richtigen Weg gebracht.
Hast Du Bock mal zu chatten da könnten wir uns besser über C unterhalten

ShadowEater@gmx.net
wie gesagt, wenn Du Lust hast
;-)

Bye
WD
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
17.08.2006, 20:27 Uhr
kronos
Quotenfisch
(Operator)


'ne kreisförmige Liste, na sowas. In der letzten Klasur hab' ich genau sowas geschrieben und hab' keine Punkte dafür bekommen, weil ich für head und tail keine extra-members verwendet hab'
--
main($)??<-$<='?'>>2?main($-!!putchar(
(("$;99M?GD??(??/x0d??/a:???;a"+'?'/4)
??($??)+'?'/3-2-1+$%2)??''?')):'?';??>
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
18.08.2006, 12:12 Uhr
0xdeadbeef
Gott
(Operator)


Die Liste ist nicht kreisförmig, sondern eine Dummy-Liste. Sollte allerdings recht leicht in eine Ringliste umzuschreiben sein.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: