| [C++] Stack |
| Autor: Cefour |
Views: 8001 |
| Datum: 04.09.2006 - 21:24 |
|
|
Kochrezept für C++ von Michael Burzan
Wie schreibe ich ein Stack?
Erstmal die Frage was ist ein Stack?
Für die Leute die es nicht wissen, ein Stack ist eine Datenstruktur, in der man nur ein Element oben drauf legen kann und auch nur von oben wieder abnehmen kann. Der Stack ist einer der einfachsten Datenstrukturen die es gibt.
Die Üblichen Funktionen für den Stack sind push(), pop(), isempty(), clear();
Erstmal die Header:
 C / C++ Code |
//stack.h
class stack
{
public:
// Default Konstruktor
Stack (void);
// Erzeugt ein Objekt der Klasse \"stack\" von der größe \"size\"
Stack(const int size);
// Copy Konstruktor
Stack(const Stack &a);
// Destruktor
~Stack();
// Legt ein Element auf dem Stack ab
void push(const double x);
// Nimmt das erste Element vom Stack
double pop(void);
// Leert den Stack
void clear();
// Vergleicht ob zwei Stacks miteinander gleich sind
bool equal(Stack a);
// Invertiert den Stack, d.h. das unterste Element ist oben
void invert(Stack a);
// Wieviel ist vom Stack benutzt
int get_used(void) const;
// Sagt wieviel Kapazität der Stack hat
int get_capacity (void) const;
// Prüft ob der Stack leer ist
bool empty(void) const;
// Prüft ob der Stack voll ist
bool full (void) const;
// Gibt den Stack aus
void print();
// ist eine statische Funktion die sagt:
// Wie hoch ist die Default Capcity des Stack
// wenn ich ein Stack mit dem Default Konstruktor
// schreibe
static int get_default_capacity();
// Setzt die Default Kapazität
static void set_default_capacity(const int dc);
private:
// Initialisiert den Stack mit einer bestimmten Größe
void initialisize(const int u);
// Die Kapazität des Stacks
int capacity;
// Benutzt
int used;
// Die Elemente des Stack
double * content;
// Den Default Wert für die Kapazität
static int default_capacity;
};
|
Jetzt noch die CPP - Datei
Erstmal die Headers die man braucht.
 C / C++ Code |
//stack.cpp
#include \"stack.h\"
#include <iostream>
|
"using namespace std" deshalb, um sich ein bisschen Syntax zu sparen. Ansonsten müßte man "std::cout" schreiben
 C / C++ Code |
|
Das ist ein Konstruktor wenn man ein Objekt der Klasse anleget. Er wird z.B "Stack stack;" aufgerufen. In der Funktion selber wird die private Funktion "initialisize" aufgerufen die einen statischen Wert namens "default_capacity" hat.
 C / C++ Code |
Stack::Stack()
{
initialisize(default_capacity);
}
|
Ein Weitere Konstruktor der einen Stack mit einer userspezifischen Größe anlegt. "const int size" deshalb umzu verhindern das der Wert von "size" geändert wird.
 C / C++ Code |
Stack::Stack(const int size)
{
initialisize(size);
}
|
Zitat von wikipedia |
Der Kopierkonstruktor ist ein spezieller Konstruktor, der eine Referenz auf ein Objekt des selben Typs
als Parameter entgegennimmt und die Aufgabe hat, eine Kopie des Objektes zu erstellen.
|
z.B
 C / C++ Code |
get_stack()
{
Stack stack(20);
// Aufruf des Kopie Konstruktor
return stack;
}
Stack::Stack(const Stack &a)
{
initialisize(a.get_used());
for(int i = 0; i < a.get_used(); i++)
{
push(a.content[i]);
}
}
|
Destruktor dieser wird aufgerufen um einen Stack zu zerstören. Dies macht die Laufzeitumgebung
automatisch. Den Destruktor muss man also nicht Explicit aufrufen.
Er gibt einfach mittels delete den Speicher wieder frei
 C / C++ Code |
|
Gibt ein Wert in den Stack rein.
Er überprüft ob der Stack voll ist, falls das so ist bricht er ab. An dieser Stelle sollte
man eigentlich eine Exception fahren, dies kommt in späteren Tutorials.
Dann übergibt er in das Array content an der Position used den Wert von x.
used ist eine private Membervariable. Normalerweise hat man keinen Zugriff drauf,
da aber die Funktion push() Mitglied der Klasse ist, kann man auf used zugreifen.
Als letzten Schritt muss man used um eine position nach oben rechnen.
Damit der nächste Wert der eingefügt wird an der richtigen Stelle ist.
 C / C++ Code |
void Stack::push(const double x)
{
if (full())
return;
content[used] = x;
used ++;
}
|
Hollt einen Wert aus dem Stack heraus.
Er überprüft ob der Stack leer ist, falls das so ist gibt er einen Fehlercode
-100 raus. Dies sollte man auch mit einer Exception abfangen.
Erst rechnet er von used eins runter damit man den letzten Wert im Array content bekommt.
 C / C++ Code |
double Stack::pop(void)
{
double stack_element;
if(empty())
return -100;
used--;
stack_element = content[used];
return stack_element;
}
|
Damit der Stack sauber gemacht wird ist nichts weiter nötig als used einfach auf 0
zu setzen. Somit überschreibt der Stack alle Werte die mit push() eingefügt werden.
 C / C++ Code |
void Stack::clear()
{
used = 0;
}
|
Überprüft ob zwei Stacks gleich sind
z.b so ein Aufruf:
 C / C++ Code |
|
Diese Funktion vergleicht die capacity vom den Stack a und die capacity vom Stack b und
vergleicht gleichzeitig ob used von a genau so groß ist wie used von b.
Falls das wahr ist geht er in die innere Scheife wo er jetzt jedes Element überprüft.
 C / C++ Code |
bool Stack::equal(Stack a)
{
bool result;
if((a.get_capacity() == capacity) && ( a.get_used() == used))
{
for(int i = 0; i < used; i++ )
{
if (a.content[i] == content[i])
{
result = true;
}
else
{
return false;
}
}
}
else
{
return false;
}
return result;
}
|
Dreht einen Stack um. Das letzte Element ist das erste und das erste Element ist das letzte.
Die Funktion geht solange durch den Stack a, bis er leer ist.
Dabei pusht die Funktion einen Wert von a in den neuen Stack hinein.
 C / C++ Code |
void Stack::invert(Stack a)
{
while(!a.empty())
push(a.pop());
}
|
Gibt used zurück.
 C / C++ Code |
int Stack::get_used(void) const
{
return used;
}
|
Gibt capacity zurück.
 C / C++ Code |
int Stack::get_capacity(void) const
{
return capacity;
}
|
Prüft ob der Stack leer ist.
 C / C++ Code |
bool Stack::empty() const
{
if (used == 0)
return true;
else
return false;
}
|
Prüft ob der Stack voll ist.
 C / C++ Code |
bool Stack::full() const
{
if (used == capacity)
return true;
else
return false;
}
|
Gibt den Stack aus
 C / C++ Code |
void Stack::print()
{
for (int i = 0; i < used; i++)
{
cout<<\" \"<<content[i];
cout<<\"\\n\";
}
}
-
|
Gibt die default_capacity.
 C / C++ Code |
int Stack::get_default_capacity()
{
return default_capacity;
}
|
Setzt default_capacity auf den Wert von db.
 C / C++ Code |
void Stack::set_default_capacity(const int dc)
{
default_capacity = dc;
}
|
Initialisiert den Stack mit der Größe u.
 C / C++ Code |
void Stack::initialisize(const int u)
{
capacity = u;
used = 0;
}
|
Statische Variable die ausserhalb der Klasse initialisiert werden muss.
Dieser Wert ist für alle Objekte der Klasse gleich.
Wenn man diesen Wert ändert werden auch alle Objekte geändert die Angelegt worden sind.
 C / C++ Code |
int Stack::default_capacity = 10;
|
Somit ist der Stack fertig. Eine kleine Datenstruktur für viele Anwendungen,
wie z.B Ein Taschenrechner Programm, der Ausdrücke in der Art rechnen soll:
2 +3 +4 *7
Das ginge jetzt kein Problem!!!
Fragen zum Stack einfach in das C / C++ Forum posten.
Zum Schluss nocheinmal der ganze CPP Code:
 C / C++ Code |
//stack.cpp
#include \"stack.h\"
#include <iostream>
using namespace std;
Stack::Stack()
{
initialisize(default_capacity);
}
Stack::Stack(const int size)
{
initialisize(size);
}
Stack::~Stack()
{
}
void Stack::push(const double x)
{
if (full())
return;
content[used] = x;
used ++;
}
double Stack::pop(void)
{
double stack_element;
if(empty())
return -100;
used--;
stack_element = content[used];
return stack_element;
}
void Stack::clear()
{
used = 0;
}
bool Stack::equal(Stack a)
{
bool result;
if((a.get_capacity() == capacity) && ( a.get_used() == used))
{
for(int i = 0; i < used; i++ )
{
if (a.content[i] == content[i])
{
result = true;
}
else
{
return false;
}
}
}
else
{
return false;
}
return result;
}
void Stack::invert(Stack a)
{
while(!a.empty())
push(a.pop());
}
int Stack::get_used(void) const
{
return used;
}
int Stack::get_capacity(void) const
{
return capacity;
}
bool Stack::empty() const
{
if (used == 0)
return true;
else
return false;
}
bool Stack::full() const
{
if (used == capacity)
return true;
else
return false;
}
void Stack::print()
{
for (int i = 0; i < used; i++)
{
cout<<\" \"<<content[i];
cout<<\"\\n\";
}
}
int Stack::get_default_capacity()
{
return default_capacity;
}
void Stack::set_default_capacity(const int dc)
{
default_capacity = dc;
}
void Stack::initialisize(const int u)
{
content = new double[u];
capacity = u;
used = 0;
}
int Stack::default_capacity = 10;
-
|
Autor: Michael Burzan
|