Skip to content

Commit cfd70e5

Browse files
author
yuwei07
committed
建立maven配置pom
1 parent d697daf commit cfd70e5

File tree

105 files changed

+25619
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+25619
-0
lines changed

.idea/.name

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/compiler.xml

+16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

+509
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
package com.jwetherell.algorithms.data_structures;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/**
7+
* An AVL tree is a self-balancing binary search tree, and it was the first such
8+
* data structure to be invented. In an AVL tree, the heights of the two child
9+
* subtrees of any node differ by at most one. AVL trees are often compared with
10+
* red-black trees because they support the same set of operations and because
11+
* red-black trees also take O(log n) time for the basic operations. Because AVL
12+
* trees are more rigidly balanced, they are faster than red-black trees for
13+
* lookup intensive applications. However, red-black trees are faster for
14+
* insertion and removal.
15+
* <p>
16+
* @see <a href="https://en.wikipedia.org/wiki/AVL_tree">AVL Tree (Wikipedia)</a>
17+
* <br>
18+
* @author Justin Wetherell <[email protected]>
19+
*/
20+
public class AVLTree<T extends Comparable<T>> extends BinarySearchTree<T> {
21+
22+
private enum Balance {
23+
LEFT_LEFT, LEFT_RIGHT, RIGHT_LEFT, RIGHT_RIGHT
24+
}
25+
26+
/**
27+
* Default constructor.
28+
*/
29+
public AVLTree() {
30+
this.creator = new BinarySearchTree.INodeCreator<T>() {
31+
/**
32+
* {@inheritDoc}
33+
*/
34+
@Override
35+
public BinarySearchTree.Node<T> createNewNode(BinarySearchTree.Node<T> parent, T id) {
36+
return (new AVLNode<T>(parent, id));
37+
}
38+
};
39+
}
40+
41+
/**
42+
* Constructor with external Node creator.
43+
*/
44+
public AVLTree(INodeCreator<T> creator) {
45+
super(creator);
46+
}
47+
48+
/**
49+
* {@inheritDoc}
50+
*/
51+
@Override
52+
protected Node<T> addValue(T id) {
53+
Node<T> nodeToReturn = super.addValue(id);
54+
AVLNode<T> nodeAdded = (AVLNode<T>) nodeToReturn;
55+
nodeAdded.updateHeight();
56+
balanceAfterInsert(nodeAdded);
57+
58+
nodeAdded = (AVLNode<T>) nodeAdded.parent;
59+
while (nodeAdded != null) {
60+
int h1 = nodeAdded.height;
61+
62+
nodeAdded.updateHeight();
63+
balanceAfterInsert(nodeAdded);
64+
65+
// If height before and after balance is the same, stop going up the tree
66+
int h2 = nodeAdded.height;
67+
if (h1==h2)
68+
break;
69+
70+
nodeAdded = (AVLNode<T>) nodeAdded.parent;
71+
}
72+
return nodeToReturn;
73+
}
74+
75+
/**
76+
* Balance the tree according to the AVL post-insert algorithm.
77+
*
78+
* @param node
79+
* Root of tree to balance.
80+
*/
81+
private void balanceAfterInsert(AVLNode<T> node) {
82+
int balanceFactor = node.getBalanceFactor();
83+
if (balanceFactor > 1 || balanceFactor < -1) {
84+
AVLNode<T> child = null;
85+
Balance balance = null;
86+
if (balanceFactor < 0) {
87+
child = (AVLNode<T>) node.lesser;
88+
balanceFactor = child.getBalanceFactor();
89+
if (balanceFactor < 0)
90+
balance = Balance.LEFT_LEFT;
91+
else
92+
balance = Balance.LEFT_RIGHT;
93+
} else {
94+
child = (AVLNode<T>) node.greater;
95+
balanceFactor = child.getBalanceFactor();
96+
if (balanceFactor < 0)
97+
balance = Balance.RIGHT_LEFT;
98+
else
99+
balance = Balance.RIGHT_RIGHT;
100+
}
101+
102+
if (balance == Balance.LEFT_RIGHT) {
103+
// Left-Right (Left rotation, right rotation)
104+
rotateLeft(child);
105+
rotateRight(node);
106+
} else if (balance == Balance.RIGHT_LEFT) {
107+
// Right-Left (Right rotation, left rotation)
108+
rotateRight(child);
109+
rotateLeft(node);
110+
} else if (balance == Balance.LEFT_LEFT) {
111+
// Left-Left (Right rotation)
112+
rotateRight(node);
113+
} else {
114+
// Right-Right (Left rotation)
115+
rotateLeft(node);
116+
}
117+
118+
child.updateHeight();
119+
node.updateHeight();
120+
}
121+
}
122+
123+
/**
124+
* {@inheritDoc}
125+
*/
126+
@Override
127+
protected Node<T> removeValue(T value) {
128+
// Find node to remove
129+
Node<T> nodeToRemoved = this.getNode(value);
130+
if (nodeToRemoved==null)
131+
return null;
132+
133+
// Find the replacement node
134+
Node<T> replacementNode = this.getReplacementNode(nodeToRemoved);
135+
136+
// Find the parent of the replacement node to re-factor the height/balance of the tree
137+
AVLNode<T> nodeToRefactor = null;
138+
if (replacementNode != null)
139+
nodeToRefactor = (AVLNode<T>) replacementNode.parent;
140+
if (nodeToRefactor == null)
141+
nodeToRefactor = (AVLNode<T>) nodeToRemoved.parent;
142+
if (nodeToRefactor != null && nodeToRefactor == nodeToRemoved)
143+
nodeToRefactor = (AVLNode<T>) replacementNode;
144+
145+
// Replace the node
146+
replaceNodeWithNode(nodeToRemoved, replacementNode);
147+
148+
// Re-balance the tree all the way up the tree
149+
while (nodeToRefactor != null) {
150+
nodeToRefactor.updateHeight();
151+
balanceAfterDelete(nodeToRefactor);
152+
153+
nodeToRefactor = (AVLNode<T>) nodeToRefactor.parent;
154+
}
155+
156+
return nodeToRemoved;
157+
}
158+
159+
/**
160+
* Balance the tree according to the AVL post-delete algorithm.
161+
*
162+
* @param node
163+
* Root of tree to balance.
164+
*/
165+
private void balanceAfterDelete(AVLNode<T> node) {
166+
int balanceFactor = node.getBalanceFactor();
167+
if (balanceFactor == -2 || balanceFactor == 2) {
168+
if (balanceFactor == -2) {
169+
AVLNode<T> ll = (AVLNode<T>) node.lesser.lesser;
170+
int lesser = (ll != null) ? ll.height : 0;
171+
AVLNode<T> lr = (AVLNode<T>) node.lesser.greater;
172+
int greater = (lr != null) ? lr.height : 0;
173+
if (lesser >= greater) {
174+
rotateRight(node);
175+
node.updateHeight();
176+
if (node.parent != null)
177+
((AVLNode<T>) node.parent).updateHeight();
178+
} else {
179+
rotateLeft(node.lesser);
180+
rotateRight(node);
181+
182+
AVLNode<T> p = (AVLNode<T>) node.parent;
183+
if (p.lesser != null)
184+
((AVLNode<T>) p.lesser).updateHeight();
185+
if (p.greater != null)
186+
((AVLNode<T>) p.greater).updateHeight();
187+
p.updateHeight();
188+
}
189+
} else if (balanceFactor == 2) {
190+
AVLNode<T> rr = (AVLNode<T>) node.greater.greater;
191+
int greater = (rr != null) ? rr.height : 0;
192+
AVLNode<T> rl = (AVLNode<T>) node.greater.lesser;
193+
int lesser = (rl != null) ? rl.height : 0;
194+
if (greater >= lesser) {
195+
rotateLeft(node);
196+
node.updateHeight();
197+
if (node.parent != null)
198+
((AVLNode<T>) node.parent).updateHeight();
199+
} else {
200+
rotateRight(node.greater);
201+
rotateLeft(node);
202+
203+
AVLNode<T> p = (AVLNode<T>) node.parent;
204+
if (p.lesser != null)
205+
((AVLNode<T>) p.lesser).updateHeight();
206+
if (p.greater != null)
207+
((AVLNode<T>) p.greater).updateHeight();
208+
p.updateHeight();
209+
}
210+
}
211+
}
212+
}
213+
214+
/**
215+
* {@inheritDoc}
216+
*/
217+
@Override
218+
protected boolean validateNode(Node<T> node) {
219+
boolean bst = super.validateNode(node);
220+
if (!bst)
221+
return false;
222+
223+
AVLNode<T> avlNode = (AVLNode<T>) node;
224+
int balanceFactor = avlNode.getBalanceFactor();
225+
if (balanceFactor > 1 || balanceFactor < -1) {
226+
return false;
227+
}
228+
if (avlNode.isLeaf()) {
229+
if (avlNode.height != 1)
230+
return false;
231+
} else {
232+
AVLNode<T> avlNodeLesser = (AVLNode<T>) avlNode.lesser;
233+
int lesserHeight = 1;
234+
if (avlNodeLesser != null)
235+
lesserHeight = avlNodeLesser.height;
236+
237+
AVLNode<T> avlNodeGreater = (AVLNode<T>) avlNode.greater;
238+
int greaterHeight = 1;
239+
if (avlNodeGreater != null)
240+
greaterHeight = avlNodeGreater.height;
241+
242+
if (avlNode.height == (lesserHeight + 1) || avlNode.height == (greaterHeight + 1))
243+
return true;
244+
return false;
245+
}
246+
247+
return true;
248+
}
249+
250+
/**
251+
* {@inheritDoc}
252+
*/
253+
@Override
254+
public String toString() {
255+
return AVLTreePrinter.getString(this);
256+
}
257+
258+
protected static class AVLNode<T extends Comparable<T>> extends Node<T> {
259+
260+
protected int height = 1;
261+
262+
/**
263+
* Constructor for an AVL node
264+
*
265+
* @param parent
266+
* Parent of the node in the tree, can be NULL.
267+
* @param value
268+
* Value of the node in the tree.
269+
*/
270+
protected AVLNode(Node<T> parent, T value) {
271+
super(parent, value);
272+
}
273+
274+
/**
275+
* Determines is this node is a leaf (has no children).
276+
*
277+
* @return True if this node is a leaf.
278+
*/
279+
protected boolean isLeaf() {
280+
return ((lesser == null) && (greater == null));
281+
}
282+
283+
/**
284+
* Updates the height of this node based on it's children.
285+
*/
286+
protected int updateHeight() {
287+
int lesserHeight = 0;
288+
if (lesser != null) {
289+
AVLNode<T> lesserAVLNode = (AVLNode<T>) lesser;
290+
lesserHeight = lesserAVLNode.height;
291+
}
292+
int greaterHeight = 0;
293+
if (greater != null) {
294+
AVLNode<T> greaterAVLNode = (AVLNode<T>) greater;
295+
greaterHeight = greaterAVLNode.height;
296+
}
297+
298+
if (lesserHeight > greaterHeight) {
299+
height = lesserHeight + 1;
300+
} else {
301+
height = greaterHeight + 1;
302+
}
303+
return height;
304+
}
305+
306+
/**
307+
* Get the balance factor for this node.
308+
*
309+
* @return An integer representing the balance factor for this node. It
310+
* will be negative if the lesser branch is longer than the
311+
* greater branch.
312+
*/
313+
protected int getBalanceFactor() {
314+
int lesserHeight = 0;
315+
if (lesser != null) {
316+
AVLNode<T> lesserAVLNode = (AVLNode<T>) lesser;
317+
lesserHeight = lesserAVLNode.height;
318+
}
319+
int greaterHeight = 0;
320+
if (greater != null) {
321+
AVLNode<T> greaterAVLNode = (AVLNode<T>) greater;
322+
greaterHeight = greaterAVLNode.height;
323+
}
324+
return greaterHeight - lesserHeight;
325+
}
326+
327+
/**
328+
* {@inheritDoc}
329+
*/
330+
@Override
331+
public String toString() {
332+
return "value=" + id + " height=" + height + " parent=" + ((parent != null) ? parent.id : "NULL")
333+
+ " lesser=" + ((lesser != null) ? lesser.id : "NULL") + " greater="
334+
+ ((greater != null) ? greater.id : "NULL");
335+
}
336+
}
337+
338+
protected static class AVLTreePrinter {
339+
340+
public static <T extends Comparable<T>> String getString(AVLTree<T> tree) {
341+
if (tree.root == null)
342+
return "Tree has no nodes.";
343+
return getString((AVLNode<T>) tree.root, "", true);
344+
}
345+
346+
public static <T extends Comparable<T>> String getString(AVLNode<T> node) {
347+
if (node == null)
348+
return "Sub-tree has no nodes.";
349+
return getString(node, "", true);
350+
}
351+
352+
private static <T extends Comparable<T>> String getString(AVLNode<T> node, String prefix, boolean isTail) {
353+
StringBuilder builder = new StringBuilder();
354+
355+
builder.append(prefix + (isTail ? "└── " : "├── ") + "(" + node.height + ") " + node.id + "\n");
356+
List<Node<T>> children = null;
357+
if (node.lesser != null || node.greater != null) {
358+
children = new ArrayList<Node<T>>(2);
359+
if (node.lesser != null)
360+
children.add(node.lesser);
361+
if (node.greater != null)
362+
children.add(node.greater);
363+
}
364+
if (children != null) {
365+
for (int i = 0; i < children.size() - 1; i++) {
366+
builder.append(getString((AVLNode<T>) children.get(i), prefix + (isTail ? " " : "│ "), false));
367+
}
368+
if (children.size() >= 1) {
369+
builder.append(getString((AVLNode<T>) children.get(children.size() - 1), prefix + (isTail ? " " : "│ "), true));
370+
}
371+
}
372+
373+
return builder.toString();
374+
}
375+
}
376+
}

0 commit comments

Comments
 (0)