Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » AVL-Bäume

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 < [ 2 ]
000
29.10.2009, 20:30 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi Ihr, mal ne grundlegende Frage.

Ich hab momentan fürs Studium eine Projektarbeit, in dem ich u.A eine AVL-Baum DAtenstruktur implementieren muss.

Im moment schaut das ganze so aus:


C++:
class AVLTree : public BinarySearchTree { ... };



auf gut deutsch: ich hab bereits einen binären suchbaum "fertig".

Ich hab das einfügen von elementen nun so verändert, das es mir den einfügepfad mit speichert, so das ich ihn "rückwärts" wieder nach "oben" laufen kann, um die Balancefaktoren zu aktualisieren.

Nur: Dort habe ich nun das Problem.

Mal ein Beispiel: Ich füge in einen leeren Baum 10 Zahlen ein (von 1 bis 10)

Dann müsste sowas in der Richtung kommen:

1 2 3 l 4 5 l 6 7 l 8 ...

das "l" steht hierbei für "linksrotation".

bis zur 8 hatte ich bereits das korrekt hinbekommen. nur: dann wollte er mir den baum nach 8tens wieder links rotieren, obwohl das nicht stimmt.

(ich hab das ganze mal geprüft mit www.ibr.cs.tu-bs.de/courses/ss98/audii/applets/avlbaum/ )

meine updateBalance funktion des TreeItems sieht (nach zig erfolglosen umbauten) nun so aus, nun funktioniert gar nichts mehr wirklich.


C++:
            inline void updateBalance()
            {
                balance = 0;

                if(right && !left)
                {
                    if(right->getBalance() == 0)
                        balance = 1; // rechter überhang
                    else
                        balance = 2; // rechter überhang, muss rotiert werden
                }
                else if(!right && left)
                {
                    if(left->getBalance() == 0)
                        balance = -1; // linker überhang
                    else
                        balance = -2;//  linker überhang, muss rotiert werden
                }
            }



iwie krieg ichs grad nicht hin, ohne das jedes treeitem die komplette höhe des baumes kennt, die balancefaktoren korrekt auszurechnen.

Wo hab ich da den Denkfehler drin?
--
class God : public ChuckNorris { };

Dieser Post wurde am 29.10.2009 um 20:31 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
29.10.2009, 22:13 Uhr
0xdeadbeef
Gott
(Operator)


Jetzt die Rotation mal außen vorgelassen, im Grunde interessiert sich für die Balance-Bestimmung ja, wie die Höhe der Unterbäume sich verschiebt. In einer rekursiven Funktion ist das relativ einfach - etwa so:

C++:
int insert(tree_node *&node, int x) {
  if(node == 0) {
    node = new tree_node(x);
    return 1;
  }

  if(x == node->data) return 0;
  if(x <  node->data) {
    balance -= insert(node->left, x);
  } else {
    balance += insert(node->right, x);
  }

  return balance != 0;
}


Wenn wir einen neuen Knoten einfügen, ist in dem speziellen Unterbaum (der nur aus dem neuen Knoten besteht) einer mehr als vorher. Damit ändert sich die Balance des darüberliegenden Knoten in die entsprechende Richtung. Wenn dieser dadurch ausgeglichen wurde (wir verlassen uns ja darauf, dass std::abs(balance) <= 1), hat sich die Höhe seines Unterbaums nicht verändert, ansonsten ist sie um 1 angestiegen. Das reichen wir dann einfach nach oben hoch.

So würde ich das jedenfalls angehen - allerdings habe ich mit AVL-Bäumen lange Zeit nicht mehr arbeiten müssen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
03.11.2009, 10:40 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


hmm naja ich hab im prinzip ja ne art iterative methode,

da ich mit meiner (bereits vorhandenen) searchItem-Funktion auch schon den "suchpfad" zurückbekomme, inkl. Stelle an der ich dann das neue Item einfügen muss.

Da habe ich dann im Moment das problem, auszurechnen, wann der Baum unbalanziert ist, um dies dann mit Rotationen zu korrigieren.

Und da häng ich grad irgendwie fest, in meinen Suchpfad nach oben die Balancefaktoren zu berechnen.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
03.11.2009, 13:37 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


okay nun habe ich das so gelöst, das sich jeder Knoten die Höhe im Baum "merkt". Nun kann ich die Balance korrekt berechnen.

Ist vielleicht nicht die schönste Lösung, aber es funktioniert zumindest ;-)
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
03.11.2009, 15:16 Uhr
0xdeadbeef
Gott
(Operator)


Wie zum Geier bist du auf die Idee gekommen, Bäume iterativ zu behandeln?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
03.11.2009, 22:37 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja "ne Art" iterative methode, ist ja nicht rekursiv.

Um den Einfügepunkt zu bekommen geh ich eben so vor wie beim Suchen eines Elements (ist auch die gleiche funktion) welche mir dann die Einfügeposition hersucht. und das macht die Funktion eben nicht rekursiv
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
03.11.2009, 22:58 Uhr
0xdeadbeef
Gott
(Operator)


Hmm...Vermeidung doppelten Codes, verstehe. Der Ansatz macht AVL-Bäume natürlich unnötig kompliziert. Der Vorteil an der Rekursion ist halt, dass du nicht nach jeder Operation einen zweiten Durchlauf brauchst, um die Buchführung des Baums wieder gerade zu ziehen.

Vielleicht ließe sich da mit Makros was drehen, aber so richtig schön wär das natürlich auch nicht...hmmm...ich muss da mal in Ruhe drüber meditieren.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
04.11.2009, 09:55 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja ich fass dann halt höchstens nochmal soviele Knoten an, wie ich schon für den Hinweg gebraucht habe, sollte sich also in Grenzen halten. Weil im Prinzip muss ich das ja sowieso
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
04.11.2009, 15:56 Uhr
0xdeadbeef
Gott
(Operator)


Naja, wenn du rotieren musst, musst du auf die Art den gesamten Unterbaum anfassen.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
05.11.2009, 13:58 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


warum muss ich da denn den gesamten unterbaum anfassen? Ich bieg ein paar zeiger um und aktualisiere dann den wert dieser elemente. bei ner doppelrotation sind das dann 3 elemente, und bei ner einfachen 2. genau die, die ich eh schon anfassen muss
--
class God : public ChuckNorris { };

Dieser Post wurde am 05.11.2009 um 13:58 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ 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: