1 public class AVLTree<E> extends BST<E> {
2
3 public AVLTree() {
4 }
5
6
7 public AVLTree(java.util.Comparator<E> c) {
8 super(c);
9 }
10
11
12 public AVLTree(E[] objects) {
13 super(objects);
14 }
15
16 @Override
17 protected AVLTreeNode<E> createNewNode(E e) {
18 return new AVLTreeNode<E>(e);
19 }
20
21 @Override
22 public boolean insert(E e) {
23 boolean successful = super.insert(e);
24 if (!successful)
25 return false;
26 else {
27 balancePath(e);
28 }
29
30 return true;
31 }
32
33
34 private void updateHeight(AVLTreeNode<E> node) {
35 if (node.left == null && node.right == null)
36 node.height = 0;
37 else if (node.left == null)
38 node.height = 1 + ((AVLTreeNode<E>)(node.right)).height;
39 else if (node.right == null)
40 node.height = 1 + ((AVLTreeNode<E>)(node.left)).height;
41 else
42 node.height = 1 +
43 Math.max(((AVLTreeNode<E>)(node.right)).height,
44 ((AVLTreeNode<E>)(node.left)).height);
45 }
46
47
50 private void balancePath(E e) {
51 java.util.ArrayList<TreeNode<E>> path = path(e);
52 for (int i = path.size() - 1; i >= 0; i--) {
53 AVLTreeNode<E> A = (AVLTreeNode<E>)(path.get(i));
54 updateHeight(A);
55 AVLTreeNode<E> parentOfA = (A == root) ? null :
56 (AVLTreeNode<E>)(path.get(i - 1));
57
58 switch (balanceFactor(A)) {
59 case -2:
60 if (balanceFactor((AVLTreeNode<E>)A.left) <= 0) {
61 balanceLL(A, parentOfA);
62 }
63 else {
64 balanceLR(A, parentOfA);
65 }
66 break;
67 case +2:
68 if (balanceFactor((AVLTreeNode<E>)A.right) >= 0) {
69 balanceRR(A, parentOfA);
70 }
71 else {
72 balanceRL(A, parentOfA);
73 }
74 }
75 }
76 }
77
78
79 private int balanceFactor(AVLTreeNode<E> node) {
80 if (node.right == null)
81 return -node.height;
82 else if (node.left == null)
83 return +node.height;
84 else
85 return ((AVLTreeNode<E>)node.right).height -
86 ((AVLTreeNode<E>)node.left).height;
87 }
88
89
90 private void balanceLL(TreeNode<E> A, TreeNode<E> parentOfA) {
91 TreeNode<E> B = A.left;
92
93 if (A == root) {
94 root = B;
95 }
96 else {
97 if (parentOfA.left == A) {
98 parentOfA.left = B;
99 }
100 else {
101 parentOfA.right = B;
102 }
103 }
104
105 A.left = B.right;
106 B.right = A;
107 updateHeight((AVLTreeNode<E>)A);
108 updateHeight((AVLTreeNode<E>)B);
109 }
110
111
112 private void balanceLR(TreeNode<E> A, TreeNode<E> parentOfA) {
113 TreeNode<E> B = A.left;
114 TreeNode<E> C = B.right;
115
116 if (A == root) {
117 root = C;
118 }
119 else {
120 if (parentOfA.left == A) {
121 parentOfA.left = C;
122 }
123 else {
124 parentOfA.right = C;
125 }
126 }
127
128 A.left = C.right;
129 B.right = C.left;
130 C.left = B;
131 C.right = A;
132
133
134 updateHeight((AVLTreeNode<E>)A);
135 updateHeight((AVLTreeNode<E>)B);
136 updateHeight((AVLTreeNode<E>)C);
137 }
138
139
140 private void balanceRR(TreeNode<E> A, TreeNode<E> parentOfA) {
141 TreeNode<E> B = A.right;
142
143 if (A == root) {
144 root = B;
145 }
146 else {
147 if (parentOfA.left == A) {
148 parentOfA.left = B;
149 }
150 else {
151 parentOfA.right = B;
152 }
153 }
154
155 A.right = B.left;
156 B.left = A;
157 updateHeight((AVLTreeNode<E>)A);
158 updateHeight((AVLTreeNode<E>)B);
159 }
160
161
162 private void balanceRL(TreeNode<E> A, TreeNode<E> parentOfA) {
163 TreeNode<E> B = A.right;
164 TreeNode<E> C = B.left;
165
166 if (A == root) {
167 root = C;
168 }
169 else {
170 if (parentOfA.left == A) {
171 parentOfA.left = C;
172 }
173 else {
174 parentOfA.right = C;
175 }
176 }
177
178 A.right = C.left;
179 B.left = C.right;
180 C.left = A;
181 C.right = B;
182
183
184 updateHeight((AVLTreeNode<E>)A);
185 updateHeight((AVLTreeNode<E>)B);
186 updateHeight((AVLTreeNode<E>)C);
187 }
188
189 @Override
192 public boolean delete(E element) {
193 if (root == null)
194 return false;
195
196
197 TreeNode<E> parent = null;
198 TreeNode<E> current = root;
199 while (current != null) {
200 if (c.compare(element, current.element) < 0) {
201 parent = current;
202 current = current.left;
203 }
204 else if (c.compare(element, current.element) > 0) {
205 parent = current;
206 current = current.right;
207 }
208 else
209 break;
210 }
211
212 if (current == null)
213 return false;
214
215
216 if (current.left == null) {
217
218 if (parent == null) {
219 root = current.right;
220 }
221 else {
222 if (c.compare(element, parent.element) < 0)
223 parent.left = current.right;
224 else
225 parent.right = current.right;
226
227
228 balancePath(parent.element);
229 }
230 }
231 else {
232
233
234
235 TreeNode<E> parentOfRightMost = current;
236 TreeNode<E> rightMost = current.left;
237
238 while (rightMost.right != null) {
239 parentOfRightMost = rightMost;
240 rightMost = rightMost.right;
241 }
242
243
244 current.element = rightMost.element;
245
246
247 if (parentOfRightMost.right == rightMost)
248 parentOfRightMost.right = rightMost.left;
249 else
250
251 parentOfRightMost.left = rightMost.left;
252
253
254 balancePath(parentOfRightMost.element);
255 }
256
257 size--;
258 return true;
259 }
260
261
262 protected static class AVLTreeNode<E> extends BST.TreeNode<E> {
263 protected int height = 0;
264
265 public AVLTreeNode(E o) {
266 super(o);
267 }
268 }
269 }