Skip to content
Snippets Groups Projects
Commit fd1893cf authored by Daniel Meißner's avatar Daniel Meißner
Browse files

Added lesson 9 exercise 1.

parent 73968e78
No related branches found
No related tags found
No related merge requests found
public class AVLTree<T extends Comparable<T>> {
private class Node { // ein Knoten im Baum
T value; // Wert am Knoten
Node left; // Wurzel linker Unterbaum
Node right; // Wurzel rechter Unterbaum
int balance; // hoehe(linker Unterbaum) - hoehe(rechter Unterbaum)
Node(T val) {
value = val;
left = null;
right = null;
balance = 0;
}
}
private Node root; // Wurzel des gesamten AVL-Baums
private int size; // Anzahl Knoten im AVL-Baum
public AVLTree() {
root = null;
size = 0;
}
public int size() {
return size;
}
public boolean contains(T elem) {
Node node = root;
int diff;
while (node != null) {
diff = node.value.compareTo(elem);
if (diff == 0) {
return true;
}
else if (diff>0) {
node = node.left;
}
else {
node = node.right;
}
}
return false;
}
public void insert(T elem) {
insert(root,null,elem);
}
/*
* Rekursives Einfuegen in einen Unterbaum.
*
* node: Der Wurzelknoten des Baumes bzw. Unterbaums, in den eingefuegt wird.
* father: Vaterknoten von node, node ist linker oder rechter Sohn von father
* elem: Der einzufuegende Wert
*
* return: true, falls der Unterbaum durch das Einfuegen hoeher geworden ist,
* sonst false
*/
private boolean insert(Node node, Node father, T elem) {
int diff;
boolean grown;
int balanceDelta;
if (node==null) { // am leeren Unterbaum angekommen
node=new Node(elem); // dann wird hier ein neuer Knoten erzeugt
if (father==null) { // nur moeglich, wenn der root==null also insgesamt leerer Baum
root = node; // dann besteht der Baum jetzt aus genau einem Knoten
} // ansonsten muessen wir untersuchen, ob der neue Knoten
else if (father.value.compareTo(elem) > 0) { // linker oder rechter Sohn seines Vaters wird.
father.left = node; // Wert im Vater ist groesser, dann wird neuer Knoten
} // linker Sohn
else { // Wert im Vater ist kleiner, dann wird neuer Knoten
father.right = node; // rechter Sohn
}
size++; // Baum hat insgesamt einen Knoten mehr
return true; // Unterbaum mit node als Wurzel ist gewachsen
}
// Wenn wir hier angekommen sind, gilt node != null.
// Wir muessen also in einen der beiden Unterbaeume von node einfuegen
diff = node.value.compareTo(elem);
if (diff == 0) { // Wert elem schon im Baum vorhanden
return false; // kein Einfuegen!
}
else if (diff > 0) { // node.value > elem ==> in linken Unterbaum einfuegen
grown = insert(node.left,node,elem);
balanceDelta = 1;
}
else { // node.value < elem ==> in rechten Unterbaum einfuegen
grown = insert(node.right,node,elem);
balanceDelta = -1;
}
if (grown) { // wenn der unterbaum von node, in den wir eingefuegt haben,
node.balance += balanceDelta; // gewachsen ist, dann aendert sich der balance-Wert
} // am Knoten node
if (!grown || node.balance==0) { // Keine Hoehenaenderung oder Fall 2 (Folie 253)
return false; // Baum mit Wurzel node ist insgesamt nicht gewachsen
}
// Wenn wir hier angekommen sind, ist der Baum mit node als Wurzel gewachsen.
// Es liegt entweder Fall 1 oder Fall 3 vor.
if (node.balance==1 || node.balance==-1) { // AVL Kriterium noch erfuellt
return true; // Fall 1 (Folie 250)
} // Der Baum ist auf jeden Fall gewachsen
// Wenn wir hier angekommen sind, ist der Baum mit Wurzel node gewachsen und das
// AVL-Kriterium ist verletzt.
if (node.balance==2) {
if (node.left.balance==1) {
rotateLeftLeft(node); // Fall 3a (Folie 258)
}
else {
rotateLeftRight(node); // LR-Rotation // Fall 3b (Folie 261)
}
}
else {
if (node.right.balance==-1) {
rotateLeftRightSymmetric(node); // Fall symmetrisch zu 3a
}
else {
rotateLeftRightSymmetric(node); // RL-Rotation // Fall symmterisch zu 3b
}
}
// Ausgleichsrotationen fuehren beim Einfuegen stets dazu, dass der Unterbaum mit
// node als Wurzel nicht gewachsen ist.
return false;
}
private void rotateLeftLeft(Node w) { // vgl. Folie 258
Node v = w.left;
Node a1 = v.left;
Node a2 = v.right;
Node b = w.right;
T tmpval;
Node tmpnode;
tmpval = w.value; // Werte in den Knoten tauschen
w.value = v.value;
v.value = tmpval;
tmpnode = w; // Verweise auf Knoten tauschen
w = v; // damit anschliessend wieder gilt:
v = tmpnode; // in Knoten v liegt v.value und in w liegt w.value
v.left = a1; // Verweise umhaengen
v.right = w;
w.left = a2;
w.right = b;
v.balance = 0; // Unterbaeume ab v und w sind jetzt auf jeden Fall
w.balance = 0; // vollstaendig ausgeglichen
}
private void rotateLeftRight(Node w) {
Node v = w.left;
Node u = v.right;
Node a1 = v.left;
Node a2 = u.left;
Node a3 = u.right;
Node b = w.right;
T tmpval;
Node tmpnode;
tmpval = w.value; // Werte in den Knoten tauschen
w.value = u.value;
u.value = tmpval;
tmpnode = w; // Verweise auf Knoten tauschen
w = u; // damit anschliessend wieder gilt:
u = tmpnode; // in Knoten v liegt v.value und in w liegt w.value
u.left = v;
u.right = w;
v.left = a1;
v.right = a2;
w.left = a3;
w.right = b;
u.balance = 0;
v.balance = 0;
w.balance = 0;
}
private void rotateLeftLeftSymmetric(Node w) { // vgl. Folie 258
Node v = w.right;
Node a1 = v.right;
Node a2 = v.left;
Node b = w.left;
T tmpval;
Node tmpnode;
tmpval = w.value; // Werte in den Knoten tauschen
w.value = v.value;
v.value = tmpval;
tmpnode = w; // Verweise auf Knoten tauschen
w = v; // damit anschliessend wieder gilt:
v = tmpnode; // in Knoten v liegt v.value und in w liegt w.value
v.right = a1; // Verweise umhaengen
v.left = w;
w.right = a2;
w.left = b;
v.balance = 0; // Unterbaeume ab v und w sind jetzt auf jeden Fall
w.balance = 0; // vollstaendig ausgeglichen
}
private void rotateLeftRightSymmetric(Node w) {
Node v = w.right;
Node u = v.left;
Node a1 = v.right;
Node a2 = u.right;
Node a3 = u.left;
Node b = w.left;
T tmpval;
Node tmpnode;
tmpval = w.value; // Werte in den Knoten tauschen
w.value = u.value;
u.value = tmpval;
tmpnode = w; // Verweise auf Knoten tauschen
w = u; // damit anschliessend wieder gilt:
u = tmpnode; // in Knoten v liegt v.value und in w liegt w.value
u.left = v;
u.right = w;
v.right = a1;
v.left = a2;
w.right = a3;
w.left = b;
u.balance = 0;
v.balance = 0;
w.balance = 0;
}
}
public class Aufgabenblatt_9Aufgabe_1 {
public static void main(String[] args) {
AVLTree<Integer> avltree = new AVLTree();
avltree.insert(50);
avltree.insert(42);
avltree.insert(23);
avltree.insert(2342);
avltree.insert(55);
avltree.insert(13);
avltree.insert(37);
System.out.println("Anzahl der Elemente: " + avltree.size());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment