# listen in c++?



## mts (8. März 2002)

hi,

kann ich in c++ mit instanzen auch listen bilden oder so(so das ich wie in c eine liste mit structrurenb bilden kann)?

thx 
mts


----------



## Robert Martinu (8. März 2002)

Du kannst verlinkte Listen auch objektorientiert implementieren - kein Problem dabei.


----------



## mts (8. März 2002)

*wie?*

wie sieht das dann aus, mach ich dann in meiner klasse unter privat(bei den daten) einen pointer der dann auf das nächste element oder auf NULL zeigt???? 

wie kann ich die instanzen dynamisch erzeugen??? mit sowas wie malloc(ist das nicht new?????). und löschen kann ich glaub mit delete, oder??


----------



## Robert Martinu (8. März 2002)

Ist zwar doppelt verlinkt, aber das Prinzip lässt sich erkennen.



```
#include <iostream>
using namespace std;

class Knoten
{
public:
	//Konstruktor
	Knoten(void);
	//Konstruktor MK2
	Knoten (char* Name, int Alter);
	//Destruktor
	~Knoten();

	//Methoden
	void SetzteAlter(int Alter);
	void SetzteName(char* Name);

	void SetzteNachfolger(Knoten* Nachfolger);
	Knoten* HoleNachfolger(void);

	void SetzteVorgaenger(Knoten *Vorgaenger);
	Knoten* HoleVorgaenger(void);

	void Ausgabe(void);

	private:
		//Attribute
		char* m_Name;
		int m_Alter;

		//Zeiger auf den nächsten Knoten
		Knoten* m_Nachfolger;
		//Zeiger auf den vorhergehenden Knoten
		Knoten* m_Vorgaenger;
};

Knoten::Knoten(void)
{
	m_Vorgaenger=NULL;
	m_Nachfolger=NULL;
	m_Name=NULL;
	m_Alter=0;
}

Knoten::Knoten(char* Name, int Alter)
{
	m_Vorgaenger=NULL;
	m_Nachfolger=NULL;
	m_Alter=Alter;
	m_Name=new char[strlen(Name+1)];
	strcpy(m_Name,Name);
}


Knoten::~Knoten()
{
	if(m_Name)
	{
		delete m_Name;
	}
}


//Alter zuweisen
void Knoten::SetzteAlter(int Alter)
{
	m_Alter=Alter;
}

//den Namen zuweisen

void Knoten::SetzteName(char* Name)
{
	if(m_Name!=NULL)
	{
		delete m_Name;
	}
	//Feld mit passender Läange reservieren
	m_Name=new char[strlen(Name)+1];
	strcpy(m_Name,Name);
}

//Das Attribut m_Nachfolger aud den übergebenen Wert setzten

void Knoten::SetzteNachfolger(Knoten* Nachfolger)
{
	m_Nachfolger=Nachfolger;
}

//Zeiger auf den Nachfolger zurückgeben
Knoten* Knoten::HoleNachfolger(void)
{
	return m_Nachfolger;
}

//Vorgänger setzten
void Knoten::SetzteVorgaenger(Knoten* Vorgaenger)
{
	m_Vorgaenger=Vorgaenger;
}


//Vorgänger holen
Knoten* Knoten::HoleVorgaenger(void)
{
	return m_Vorgaenger;
}

//Im Knoten gespeicherte Daten ausgeben

void Knoten::Ausgabe(void)
{
	cout<<m_Name<<endl<<m_Alter<<endl<<endl;
}




class Liste
{
public:
	Liste(void); //Konstruktor
	~Liste(void); //Destruktor

	void Hinzufuegen(Knoten* NeuerKnoten);
	void Ausgeben(void);
	void Loeschen(void);

private:
	Knoten* ListenAnfang;
	Knoten* ListenEnde;
};


//Die Zeiger ListenAnfang und ListenEnde mit NULL initialisieren

Liste::Liste(void)
{
	ListenEnde=ListenAnfang=NULL;
}

//Alle Knoten der Liste löschen, wenn die Liste gelöscht wird
Liste::~Liste(void)
{
	Loeschen();
}

//Knoten in die Liste einfügen
void Liste::Hinzufuegen(Knoten* NeuerKnoten)

{
	//Wenn die Liste leer war, müssen sowohl Kopf- als auch Endknoten auf den
	//1. Knoten zeigen
	if(ListenAnfang==NULL)
	{
		ListenAnfang=NeuerKnoten;
		ListenEnde=NeuerKnoten;
	}
	//Ansonsten wird der neue Knoten hinter dem Zeiger Listenende
	//eingefügt, der vorgänger des neuen Knoten ist damit der Knoten, 
	//auf den der Zeiger jetzt zeigt. Zum Schluss muss Listenende noch auf den
	//neuen Knoten gesetzt werden
	else
	{
		ListenEnde->SetzteNachfolger(NeuerKnoten);
		NeuerKnoten->SetzteVorgaenger(ListenEnde);
		ListenEnde=NeuerKnoten;
	}
}

// Alle Knoten der Liste ausgeben
void Liste::Ausgeben()
{
	Knoten* p=ListenAnfang;

	//solange p nicht NULL ist
	while(p)
	{
		//Ausgeben der Attribute
		p->Ausgabe();
		//und p wird auf den NachfolgeKoten von p gesetzt
		p=p->HoleNachfolger();
	}
}


//Alle Knoten der Liste Löschen
void Liste::Loeschen()
{
	while(ListenEnde->HoleVorgaenger())
	{
		ListenEnde=ListenEnde->HoleVorgaenger();
		delete ListenEnde->HoleNachfolger();
		ListenEnde->SetzteNachfolger(NULL);
	}
}



//Demostration der Listenfunktionalität

int main(void)
{
	Liste DieListe;		//Liste instanzieren

	//einen neunen Knoten erzeugen
	Knoten* k=new Knoten("Horst", 12);
	//den Knoten einfügen
	DieListe.Hinzufuegen(k);

	//Noch einen Knoten erzeugen, diesmal noch ohne Inhalt
	k=new Knoten();

	//den Knoten Werte zuweisen
	k->SetzteAlter(32);
	k->SetzteName("Irgendwer");

	//ebenfalls einfügen
	DieListe.Hinzufuegen(k);

	//das Eingegebene ausgeben
	DieListe.Ausgeben();

	//die Liste jetzt löschen
	DieListe.Loeschen();

	return 0;
}
```


----------



## mts (8. März 2002)

*danke*

vielen dank, 
du hast mir sehr weiter geholfen


----------



## Christian Fein (11. März 2002)

Das ist natuerlich eine moeglichkeit 
aber wozu das rat neu erfinden und nicht einfach die list aus der 
Standartlibrary nehmen ?

Beispiel fuer string:

```
// Template list fuer string instanzieren
list<string> meineListe;

// moegliche methoden

int size() const;
// Anzahl momentaner Elemente

bool empty() const;
// ist leer true.

int max_size() const;
// max Elemente die aufgenommen werden könnte

element front();
// gibt erstes Element zurueck

element back();
// gibt letztes Element zurueck

swap(ContainerTyp Two);
// Vertauscht zwei Container

clear();
// Loescht inhalt der Container

iterator insert(iterator pos, element x);
/* Fuegt an pos das element x ein und gibt iteratorposition des eingefuegten elemets zurück */

iterator erase(iterator pos);
/* loescht element an pos gibt iterator auf dahinter liegende Element zurueck */

iterator erase(iterator anf, iterator end);
/* loescht einschliesslich anf bis ende gibt gibt iterator auf element nach dem geloeschten rurueck */

void splice(itterator pos, list<string>& x)
// fuegt vor pos die liste x ein. Es muss eine andere Liste sein

void splice(iterator pos, list<string> &x, iterator posix)
// fuegt element an der stelle posx der liste x  vor pos ein.

void splce(iterator pos ....

.... //
```
keine lust mehr ... rest siehe msdn stl list 
ebenso ist stack<T> deque<T> vector<T> interressant.


----------



## Robert Martinu (11. März 2002)

Die Libaries sind durchaus eine gute Idee  - aber imo ists nicht schlecht, die Standardalgos/Strukturen mal selber geschrieben zu haben.


----------



## Daniel Toplak (11. März 2002)

@Daishi da geb ich dir recht. Meiner Meinung nach, sollte man sich selbst erst mal eine Listen-Klasse aufbauen, bevor man die aus den Lib's verwendet, denn wenn man das Prinzip der einfach- und doppelt verketteten Listen begriffen hat, dann kann man ja immer noch auf die Lib's zurückgreifen.

Gruss Homer (Der sich auch gerade mit solchen Listen beschäfftigt)


----------



## Daniel Toplak (12. März 2002)

Juhu, hab's geschafft eine doppelt-verkettete Listen-Klasse zu erstellen und das ganz ohne Lib's. 

Gruss Homer (der noch ziemlich am anfang mit C/C++ ist)


----------



## leifg (16. April 2002)

@Daishi: in deinem programmbeispiel is aber noch ein dicker fehler:

wenn du mehr als 2 elemente in deine liste einfügst wird eine endlosschleife da dann aus irgendeinem grund kein zeiger mehr auf null zeigt.

mfg
leifg


----------



## sven_raven (17. April 2002)

warum wollen immer alle mit listen arbeiten??

Baumstrukturen sind doch viel besser...


----------



## Xeragon (19. April 2002)

Alle Datenstrukturen haben ihre Vor-/Nachteile, die in jedem Fall einzeln abgewogen werden müssen, es gibt keine "ultimative" Datenstruktur (und somit sind Listen oft gegenüber Gäumen vorzuziehen).


----------



## Christian Fein (19. April 2002)

naja fifo / filo strukturen sind auch nicht grade sehr 
maechtig in der art und weise wie mann sie anwenden kann.
Aber in dem bereich in denen mann sie nutzt sind sie halt 
klasse und einfach schnell


----------



## RobertBerlin (9. Juli 2003)

*Die lieben Listen*

Sorry, ich hoffe, meine Frage ist nicht zu lang.
Ansonsten einfach rausschmeißen, ok?

Ich bin neulich über dieses interessante Listen-Listing gestoßen.
Ich habe probiert, mir selbst daraus eine abzuleiten.
Mein Lehrer steht darauf, ein Programm in ...
eigene h-Dateien, cpp-Dateien und eine Main-Datei zu zerstücken.
Das ist immer ein Kampf mit den #include Angaben!!!

Nun habe ich probiert eine eigene Liste zu erschaffen.
Erst mal ganz easy ohne Löschen oder so.

Ich habe zwei Probleme:
1. Bei einem einfachen Test liefen die unten stehenden Zeilen nicht.
Sieht jemand den Fehler?
2. In einer Erweiterung soll ich die Liste TEMPLATE-.fähig machen.
Also kein Int Data mehr sondern ein T Data.
Stimmt es, dass das nicht mit der liste.h Datei mehr funktioniert???
Das leuchtet mir nicht ein.



Hier die Zeilen:
//--liste.h----------------------------------------------------

1 class Knoten
2  {
3    friend class Liste; //Klasse Knoten darf von
4  private:            //Klasse Liste benutzt werden
5    int    data;
6    Knoten *next;
7
8  public:
9    Knoten () {next = NULL;}
10    Knoten (int dat)  {next = NULL; data = dat; }
11  };
12
13 class Liste
14 {
15  private:
16    Knoten *top;
17    Knoten *end;
18
19  public:
20    Liste ()  {  top = NULL; end = NULL;   }
21    void insert (Knoten *);
22 };

//--list.cpp----------------------------

1 #include "liste.h"
2  void Liste::insert(Knoten *poi)
3  {
4       if (end==NULL) end = poi;
5      poi->next=top;
6       top = poi;
7  }


//--main.cpp--------------------------

1  #include <iostream.h>
2  #include <stdio.h>
3
4  #include "liste.h"
5
6 int main ()
7{
8  Liste meineListe();
9  int a = 3;
10
11 Knoten *ZeigerAufKnoten = new Knoten (a);
12
13  meineListe.insert (ZeigerAufKnoten);
14
15  cin.ignore();
16  return 0;
}



VIELEN vielen Dank für die Hilfe


----------

