AuD
Lecture 'Algorithmen und Datenstrukturen' (code examples)
AVLTree.java
Go to the documentation of this file.
1package aud;
2
14public class AVLTree<Key extends Comparable<Key>,Value>
15 extends BinarySearchTree<Key,Value> {
16
24 protected class AVLNode extends BinarySearchTree<Key,Value>.Node {
25 AVLNode(AVLTree<Key,Value> tree,Key key,Value value) {
26 super(tree,key,value);
27 tree_=tree;
28 height_=1;
29 }
30
32 public int computeHeight() {
33 int hl=getLeft() !=null ? ((AVLNode) getLeft()) .computeHeight() : 0;
34 int hr=getRight()!=null ? ((AVLNode) getRight()).computeHeight() : 0;
35 return 1+(hl>hr ? hl : hr);
36 }
37
38 int height_;
39
43 public int getHeight(AVLNode node) { return node==null ? 0 : node.height_; }
44
46 void updateHeight() {
47 int hl=getHeight((AVLNode) getLeft());
48 int hr=getHeight((AVLNode) getRight());
49 height_=1+(hl>hr ? hl : hr);
50 }
51
53 public int getBalance() {
54 return getHeight((AVLNode) getLeft())-getHeight((AVLNode) getRight());
55 }
57 public boolean isBalanced() {
58 int b=getBalance();
59 return -1<=b && b <=+1;
60 }
61
62 @Override protected String textLabel() {
63 return getData().toString()+" ("+height_+")";
64 }
65 }
66
68 @Override protected Node createNode(Key key,Value value) {
69 return new AVLNode(this,key,value);
70 }
71
73 public AVLTree() {
74 super();
75 }
76
78 public int getHeight() { return ((AVLNode) head_).height_-1; }
79
80 @Override protected void onInsert(Node _node) {
81 AVLNode node=(AVLNode) _node;
82 AVLNode parent=(AVLNode) node.getParent();
83
84 parent.updateHeight(); // update immediate parent
85
86 if (parent!=head_) // rebalcing requires to check grand parent
87 rebalance(node,parent,(AVLNode) parent.getParent());
88 }
89
90 protected void rebalance(AVLNode x,AVLNode y,AVLNode z) {
91 assert(x!=null && x!=head_);
92 assert(y!=null);
93 assert(x.isBalanced());
94 assert(y==head_ || y.isBalanced());
95
96 if (z==null) {
97 assert(y==head_); // nothing to do
98 return;
99 }
100
101 z.updateHeight();
102
103 if (z!=head_) {
104 if (!z.isBalanced()) {
105
106 AVLNode b=(AVLNode) restructure(x); // new root
107 AVLNode a=(AVLNode) b.getLeft();
108 AVLNode c=(AVLNode) b.getRight();
109
110 a.updateHeight();
111 c.updateHeight();
112
113 b.updateHeight();
114
115 assert(b.isBalanced());
116 assert(a.isBalanced());
117 assert(c.isBalanced());
118
119 y=b;
120 z=(AVLNode) b.getParent(); // prepare for traversal (below)
121 // note: z may equal head_ now!
122 }
123
124 rebalance(y,z,(AVLNode) z.getParent()); // traverse to root
125
126 } else {
127 z.updateHeight(); // z==head_
128 }
129 }
130
134 @Override public Value remove(Key key) {
135 throw new UnsupportedOperationException("AVLTree#remove");
136 }
137
138
140 @Override protected void checkConsistency(Node node) {
141 super.checkConsistency(node);
142
143 AVLNode anode=(AVLNode) node;
144 assert(anode.height_==anode.computeHeight());
145 assert(anode.isBalanced());
146
147 if (anode.height_!=anode.computeHeight())
148 throw new RuntimeException("imvalid height for node '"+anode+"': "+
149 anode.height_+"!="+anode.computeHeight());
150 if (!anode.isBalanced())
151 throw new RuntimeException("unbalanced node '"+anode+"': balance="
152 +anode.getBalance());
153 }
154
156 public static void main(String[] args) {
157
158 AVLTree<String,Object> tree=new AVLTree<String,Object> ();
159 System.out.println(tree);
160
161 String[] keys={"c","b","a"};
162
163 for (String key : keys) {
164 System.out.println("insert '"+key+"'");
165 tree.insert(key,null);
166 System.out.println(tree);
167 System.out.println(tree.toText());
168 tree.checkConsistency();
169 }
170 }
171}
Node head_
Node in an AVLTree.
Definition: AVLTree.java:24
String textLabel()
Definition: AVLTree.java:62
boolean isBalanced()
|getBalance()|<=1 ?
Definition: AVLTree.java:57
int getBalance()
get height difference between left and right subtree
Definition: AVLTree.java:53
int getHeight(AVLNode node)
get height of subtree
Definition: AVLTree.java:43
int computeHeight()
compute height of subtree recursively (for testing only)
Definition: AVLTree.java:32