mit Hilfe eines binären Baumes möchte ich einen Vektor sortieren. Die Funktion sort() soll nacheinander die int-Werte des Vektors an die insert() Funktion übergeben. Die insert() Funktion soll die Zahlen an der entsprechenden Stelle in den Baum einfügen. Leider erhalte ich mit meinem folgenden Code einige Fehlermeldungen (siehe unten). Wäre super, wenn mir hier jemand weiterhelfen könnte. Danke!
// Gib neuen Baum zurück, welcher o enthält template <typename object>
bst<object> *insert(object v)
{
if (this == NULL) {
bst<object> node = new bst<object>(v);
return node;
}
if (v < value) return left->insert(v);
else return right->insert(v);
}
Und hier die aufrufende Sortierfunktion:
C/C++ Code:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
// Sortiere alle Zahlen aus dem Vektor 'vec' durch hinzufügen in bst<int> void sort(vector<int> &vec)
{
bst<object> tree;
for (int i=0; i<vec.size(); i++) {
tree = tree->insert(vec[i]);
}
return;
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10
// Sortiere alle Zahlen aus dem Vektor 'vec' durch hinzufügen in bst<int> void sort(vector<int> &vec)
{
bst<object> tree;
for (int i=0; i<vec.size(); i++) {
tree = tree->insert(vec[i]);
}
return;
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10
// Sortiere alle Zahlen aus dem Vektor 'vec' durch hinzufügen in bst<int> void sort(vector<int> &vec)
{
bst<object> tree;
for (int i=0; i<vec.size(); i++) {
tree = tree->insert(vec[i]);
}
return;
}
Mein code führt zu folgender Fehlermeldung:
Code:
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
bst.h: In function ‘bst<object>* insert(object)’:
bst.h:23: error: invalid use of ‘this’ in non-member function
bst.h:29: error: ‘value’ was not declared in this scope
bst.h:29: error: request for member ‘insert’ in ‘std::left->’, which is of non-class type ‘std::ios_base& ()(std::ios_base&)’
bst.h:30: error: request for member ‘insert’ in ‘std::right->’, which is of non-class type ‘std::ios_base& ()(std::ios_base&)’
sort.cpp:12: error: variable or field ‘sort’ declared void
sort.cpp:12: error: ‘vector’ was not declared in this scope
sort.cpp:12: error: expected primary-expression before ‘int’
Code:
1 2 3 4 5 6 7 8
bst.h: In function ‘bst<object>* insert(object)’:
bst.h:23: error: invalid use of ‘this’ in non-member function
bst.h:29: error: ‘value’ was not declared in this scope
bst.h:29: error: request for member ‘insert’ in ‘std::left->’, which is of non-class type ‘std::ios_base& ()(std::ios_base&)’
bst.h:30: error: request for member ‘insert’ in ‘std::right->’, which is of non-class type ‘std::ios_base& ()(std::ios_base&)’
sort.cpp:12: error: variable or field ‘sort’ declared void
sort.cpp:12: error: ‘vector’ was not declared in this scope
sort.cpp:12: error: expected primary-expression before ‘int’
Code:
1 2 3 4 5 6 7 8
bst.h: In function ‘bst<object>* insert(object)’:
bst.h:23: error: invalid use of ‘this’ in non-member function
bst.h:29: error: ‘value’ was not declared in this scope
bst.h:29: error: request for member ‘insert’ in ‘std::left->’, which is of non-class type ‘std::ios_base& ()(std::ios_base&)’
bst.h:30: error: request for member ‘insert’ in ‘std::right->’, which is of non-class type ‘std::ios_base& ()(std::ios_base&)’
sort.cpp:12: error: variable or field ‘sort’ declared void
sort.cpp:12: error: ‘vector’ was not declared in this scope
sort.cpp:12: error: expected primary-expression before ‘int’
bst<object>::bst(object o)
Das <object> kannst beim Constructor weglassen.
bst::bst(object o)
reicht.
rya.
_________________ Sometimes it pays to stay in bed in Monday, rather than spending the rest of the week debugging Monday's code. ~Dan Salomon
Meine Projekte
Das löst leider nicht das Problem. Ich erhalte ohne <object> folgende Meldungen zusätzlich:
Code:
bst.h:12: error: ‘template<class object> class bst’ used without template parameters
bst.h:12: error: ISO C++ forbids declaration of ‘bst’ with no type
bst.h:12: error: declaration of template ‘template<class object> int bst(object)’
Code:
bst.h:12: error: ‘template<class object> class bst’ used without template parameters
bst.h:12: error: ISO C++ forbids declaration of ‘bst’ with no type
bst.h:12: error: declaration of template ‘template<class object> int bst(object)’
Code:
bst.h:12: error: ‘template<class object> class bst’ used without template parameters
bst.h:12: error: ISO C++ forbids declaration of ‘bst’ with no type
bst.h:12: error: declaration of template ‘template<class object> int bst(object)’
// Sortiere alle Zahlen aus dem Vektor 'vec' durch hinzufügen in bst<int> void sort(vector<int> &vec)
{
bst<object> tree;
for (int i=0; i<vec.size(); i++)
{
tree = tree->insert(vec[i]);
}
// Sortiere alle Zahlen aus dem Vektor 'vec' durch hinzufügen in bst<int> void sort(vector<int> &vec)
{
bst<object> tree;
for (int i=0; i<vec.size(); i++)
{
tree = tree->insert(vec[i]);
}
// Sortiere alle Zahlen aus dem Vektor 'vec' durch hinzufügen in bst<int> void sort(vector<int> &vec)
{
bst<object> tree;
for (int i=0; i<vec.size(); i++)
{
tree = tree->insert(vec[i]);
}
return;
}
Kann mir jemand erklären, wieso ich folgenden Fehler bekomme?
Code:
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
sort.cpp: In function ‘void sort(std::vector<int, std::allocator<int> >&)’:
sort.cpp:14: error: ‘object’ was not declared in this scope
sort.cpp:14: error: template argument 1 is invalid
sort.cpp:14: error: invalid type in declaration before ‘=’ token
sort.cpp:14: error: ‘object’ cannot appear in a constant-expression
sort.cpp:14: error: template argument 1 is invalid
sort.cpp:14: error: invalid conversion from ‘int*’ to ‘int’
sort.cpp:16: error: base operand of ‘->’ is not a pointer
Code:
1 2 3 4 5 6 7 8
sort.cpp: In function ‘void sort(std::vector<int, std::allocator<int> >&)’:
sort.cpp:14: error: ‘object’ was not declared in this scope
sort.cpp:14: error: template argument 1 is invalid
sort.cpp:14: error: invalid type in declaration before ‘=’ token
sort.cpp:14: error: ‘object’ cannot appear in a constant-expression
sort.cpp:14: error: template argument 1 is invalid
sort.cpp:14: error: invalid conversion from ‘int*’ to ‘int’
sort.cpp:16: error: base operand of ‘->’ is not a pointer
Code:
1 2 3 4 5 6 7 8
sort.cpp: In function ‘void sort(std::vector<int, std::allocator<int> >&)’:
sort.cpp:14: error: ‘object’ was not declared in this scope
sort.cpp:14: error: template argument 1 is invalid
sort.cpp:14: error: invalid type in declaration before ‘=’ token
sort.cpp:14: error: ‘object’ cannot appear in a constant-expression
sort.cpp:14: error: template argument 1 is invalid
sort.cpp:14: error: invalid conversion from ‘int*’ to ‘int’
sort.cpp:16: error: base operand of ‘->’ is not a pointer
Pack Deinen Code doch mal vollständig auf codepad drauf und schick den Link rum.
Eines vorweg: Dein insert ist eine nicht-statische Elementfunktion, die einen "this==NULL" Vergleich enthält. Das ist schonmal sehr verdächtig. Ich würde es als statische Elementfunktion machen:
@Sebastian: Das Problem ist, dass die verwendeten Methoden aus der Klasse bst bereits vordeklariert sind. Das heißt, ich kann aus der insert() Funktion mit EINEM Argument keine insert() Funktion mit ZWEI Argumenten machen. Es wäre tatsächlich schön, wenn ich dieser Funktion immer den root pointer übergeben könnte. Ich darf dieser Funktion aber nur EIN Argument vom Typ "object" übergeben. Demzufolge muss ich doch über den this pointer auf den entsprechenden Knoten zugreifen, oder?
@Siassei: Ich verstehe gerade nicht so ganz, wieso die sort() Funktion zu einer Klasse gehören muss. Ich denke, sie darf definitiv nicht zur Klasse bst gehören, denn sort() erstellt doch die Objekte vom Typ bst<object>. Meinst du, es muss eine zusätzliche Klasse geben, welche die sort() Funktion enthält?
Folgende Funktionen sind in der Klasse bst fest vordefiniert und dürfen nicht verändert werden:
Die beiden Funktionen müssen nicht in der Klasse definiert werden.
Dein Fehler in der sort-Funtkion war ganz einfach, daß "object" dort unbekannt ist: du mußt schon den richtigen Datentyp angeben (im Kommentar steht es ja schon!):
C/C++ Code:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
// Sortiere alle Zahlen aus dem Vektor 'vec' durch hinzufügen in bst<int> void sort(vector<int> &vec)
{
bst<int>* tree; // <-- int statt object (und Zeiger statt Instanz) for (int i=0; i<vec.size(); i++)
{
tree = tree->insert(vec[i]);
}
}
C/C++ Code:
1 2 3 4 5 6 7 8 9
// Sortiere alle Zahlen aus dem Vektor 'vec' durch hinzufügen in bst<int> void sort(vector<int> &vec)
{
bst<int>* tree; // <-- int statt object (und Zeiger statt Instanz) for (int i=0; i<vec.size(); i++)
{
tree = tree->insert(vec[i]);
}
}
C/C++ Code:
1 2 3 4 5 6 7 8 9
// Sortiere alle Zahlen aus dem Vektor 'vec' durch hinzufügen in bst<int> void sort(vector<int> &vec)
{
bst<int>* tree; // <-- int statt object (und Zeiger statt Instanz) for (int i=0; i<vec.size(); i++)
{
tree = tree->insert(vec[i]);
}
}
Dies löst aber nur deine syntaktischen Probleme.
Der obige Funktionscode ist jedoch nicht lauffähig, weil der Baum nicht initialisiert ist (die Abfrage in der insert-Methode auf "this == NULL" wurde ja schon angesprochen!) und die Zuweisung des Rückgabewerts von der insert-Methode an 'tree' ergibt auch keinen wirklichen Sinn (bezogen auf einen Binärbaum)...
Das Problem ist, dass die verwendeten Methoden aus der Klasse bst bereits vordeklariert sind. Das heißt, ich kann aus der insert() Funktion mit EINEM Argument keine insert() Funktion mit ZWEI Argumenten machen. Es wäre tatsächlich schön, wenn ich dieser Funktion immer den root pointer übergeben könnte. Ich darf dieser Funktion aber nur EIN Argument vom Typ "object" übergeben.
Das ist nicht schlimm. Du musst die Funktion nur sinnvoll implementieren. "this==NULL" ist Quatsch, da Du die Funktion nur auf einem gültigen Objekt aufrufen darfst.
Du brauchst dann eine Fallunterscheidung: Gibt es schon einen Wurzelknoten oder gibt es ihn noch nicht? Diese Sonderbehandlung kannst Du trotzdem in einer neuen Funktion verstecken, die Dir das Leben leichter macht:
Der erste Parameter ist eine Referenz auf einen Zeiger. Der Zeiger kann also bleibend verändert werden, zB wenn es noch keinen Knoten gibt. Der zweite Parameter ist vom Typ T bzw "const T&", je nachdem, was vielversprechender bzgl Performance ist. Ich habe es aber auch benutzt, damit der 2. Parameter nicht vom Compiler dazu benutzt wird, T zu herzuleiten. Du kannst die Funktion dann auch so aufrufen:
Ich schätze, man will, dass Du bst<T>::insert als Rekursion implementierst. Das ist natürlich möglich, aber meiner Meinung nach unschön, weil es wieder eine Sonderbehandlung erfordert (nicht wegen der Rekursion, wegen der nicht-statischen Elementfunktion) und zweitens auf Kosten des automatischen Speichers geht (wegen der Rekursion).
Gruß,
SP
Zuletzt bearbeitet von Sebastian Pizer am 09:59:49 25.10.2009, insgesamt 3-mal bearbeitet
Vielen Dank für eure Hilfe!! Ich muss jetzt doch nochmal fragen und es klingt für euch wahrscheinlich total dämlich aber ich steh gerade einfach auf dem Schlauch und komme alleine nicht weiter.
Mein Problem ist, dass die insert() Funktion nur EINEN Parameter haben darf. Es darf kein Wurzelzeiger übergeben werden, sondern nur der Integer-Schlüssel. Dass this==NULL keinen Sinn macht, sehe ich jetzt. Ich wollte damit überprüfen, ob der Knoten bereits existiert. Da ich keinen root-pointer übergeben bekommen darf, muss ich doch irgendwie mit dem this-pointer arbeiten. Ich muss davon ausgehen, dass das aufrufende Objekt die Wurzel meines Baumes ist.
Meine insert() Funktion sieht noch folgendermaßen aus:
C/C++ Code:
1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10 11
template <typename object>
bst<object> *bst<object>::insert(object v)
{
if (this == NULL) {
bst<object> node = new bst<object>(v);
return node;
}
if (v < value) return left->insert(v);
else return right->insert(v);
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10 11
template <typename object>
bst<object> *bst<object>::insert(object v)
{
if (this == NULL) {
bst<object> node = new bst<object>(v);
return node;
}
if (v < value) return left->insert(v);
else return right->insert(v);
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10 11
template <typename object>
bst<object> *bst<object>::insert(object v)
{
if (this == NULL) {
bst<object> node = new bst<object>(v);
return node;
}
if (v < value) return left->insert(v);
else return right->insert(v);
}
Und die Aufrufende Funktion:
C/C++ Code:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
void sort(vector<int> &vec)
{
bst<int>* tree;
for (int i=0; i<vec.size(); i++)
{
tree = tree->insert(vec[i]);
}
return;
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10
void sort(vector<int> &vec)
{
bst<int>* tree;
for (int i=0; i<vec.size(); i++)
{
tree = tree->insert(vec[i]);
}
return;
}
C/C++ Code:
1 2 3 4 5 6 7 8 9 10
void sort(vector<int> &vec)
{
bst<int>* tree;
for (int i=0; i<vec.size(); i++)
{
tree = tree->insert(vec[i]);
}
return;
}
Es gibt im Netz viel über binäre Suchbäume (Beispiel auf Wikipedia etc.), aber ALLE die ich bisher gefunden habe, bekommen in der insert Funktion den Wurzelknoten mitübergeben, was das ganze viel einfacher macht.
Nächstes Thema anzeigen Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.
c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums
für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de
Werbekostenerstattung verdient werden kann.
Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de
enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt
(vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in
privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden.
Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere
übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.