Repository: ignl/BinarySearchTrees
Branch: master
Commit: 965006a43fea
Files: 41
Total size: 129.1 KB
Directory structure:
gitextract_wjyganpj/
├── .gitignore
├── LICENSE
├── README.md
└── Trees/
├── .gitignore
├── pom.xml
└── src/
├── main/
│ └── java/
│ └── org/
│ └── intelligentjava/
│ └── algos/
│ ├── simplestructures/
│ │ ├── LinkedList.java
│ │ ├── PriorityQueue.java
│ │ ├── Queue.java
│ │ └── Stack.java
│ └── trees/
│ ├── AVLTree.java
│ ├── AbstractBinarySearchTree.java
│ ├── AbstractSelfBalancingBinarySearchTree.java
│ ├── BinarySearchTree.java
│ ├── RedBlackTree.java
│ ├── ScapegoatTree.java
│ ├── SplayTree.java
│ ├── Treap.java
│ ├── benchmark/
│ │ ├── TreesDeleteBenchmark.java
│ │ ├── TreesInsertRandomBenchmark.java
│ │ ├── TreesInsertSortedBenchmark.java
│ │ ├── TreesSearchBenchmark.java
│ │ └── TreesSearchSameElementsBenchmark.java
│ ├── exceptions/
│ │ └── QueueOverflowException.java
│ ├── main/
│ │ └── Main.java
│ └── utils/
│ ├── ArrayUtils.java
│ ├── HeapUtils.java
│ └── MathUtils.java
└── test/
└── java/
└── org/
└── intelligentjava/
└── algos/
├── simplestructures/
│ ├── LinkedListTest.java
│ ├── PriorityQueueTest.java
│ ├── QueueTest.java
│ └── StackTest.java
└── trees/
├── AVLTreeTest.java
├── BaseBSTTest.java
├── BinarySearchTreeTest.java
├── RedBlackTreeTest.java
├── ScapegoatTreeTest.java
├── SplayTreeTest.java
├── TreapTest.java
└── utils/
├── ArrayUtilsTest.java
├── HeapUtilsTest.java
└── MathUtilsTest.java
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
Trees/.classpath
Trees/.project
Trees/.settings/org.eclipse.jdt.core.prefs
Trees/.settings/org.eclipse.m2e.core.prefs
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# BinarySearchTrees
Java binary search trees implementations and tests: AVL Tree, Red black tree, Scapegoat tree, Splay tree, Treap
Blog post and benchmarks: https://intelligentjava.wordpress.com/2015/04/09/self-balancing-binary-search-trees-comparison/
To run benchmarks:
cd Trees
mvn clean install
java -jar target/benchmarks.jar
================================================
FILE: Trees/.gitignore
================================================
/target/
================================================
FILE: Trees/pom.xml
================================================
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.intelligentjava</groupId>
<artifactId>Trees</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- Microbenchmark -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.21</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.21</version>
<!-- the processor artifact is required only during compilation and does
not need to be transitive, hence provided scope -->
<scope>provided</scope>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<compilerVersion>1.7</compilerVersion>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>benchmarks</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.1</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/simplestructures/LinkedList.java
================================================
package org.intelligentjava.algos.simplestructures;
/**
* Standard simple non circular doubly linked Linked List implementation.
*
* @author Ignas Lelys
* @created May 4, 2011
*
*/
// TODO iterator
public class LinkedList {
private Entry head;
// TODO error checking
public int get(int index) {
Entry entry = head;
for (int i = 0; i < index; i++) {
entry = entry.next;
}
return entry.element;
}
public void insert(int element) {
Entry oldHead = this.head;
this.head = new Entry(null, oldHead, element);
if (oldHead != null) {
oldHead.previous = head;
}
}
public void delete(int element) {
Entry elementEntry = search(element);
if (elementEntry != null) {
if (elementEntry.previous != null) {
elementEntry.previous.next = elementEntry.next;
} else {
this.head = elementEntry.next; // if no previous, that means we are deleting head
}
if (elementEntry.next != null) {
elementEntry.next.previous = elementEntry.previous;
}
}
}
private Entry search(int key) {
Entry entry = head;
while (entry != null) {
if (entry.element == key) {
return entry;
}
entry = entry.next;
}
return null;
}
private static class Entry {
public Entry(Entry previous, Entry next, int element) {
super();
this.previous = previous;
this.next = next;
this.element = element;
}
public Entry previous;
public Entry next;
public int element;
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/simplestructures/PriorityQueue.java
================================================
package org.intelligentjava.algos.simplestructures;
import org.intelligentjava.algos.trees.utils.ArrayUtils;
import org.intelligentjava.algos.trees.utils.HeapUtils;
/**
* Priority queue implementation.
*
* @author Ignas Lelys
* @created Apr 18, 2011
*
*/
public class PriorityQueue {
private int[] heap;
private int heapSize = 0;
public PriorityQueue() {
heap = new int[100];
}
public void insertElement(int element) {
heapSize++;
heap[heapSize - 1] = Integer.MIN_VALUE;
changeElementValue(heapSize - 1, element);
}
public void changeElementValue(int index, int newValue) {
if (heap[index] > newValue) {
throw new RuntimeException("New value is smaller than old one.");
}
heap[index] = newValue;
while (index > 0 && heap[HeapUtils.getParent(index)] < heap[index]) {
ArrayUtils.swap(heap, index, HeapUtils.getParent(index));
index = HeapUtils.getParent(index);
}
}
public int getElement() {
return heap[0];
}
public int removeElement() {
if (heapSize < 1) {
throw new RuntimeException();
}
int maxElement = heap[0];
heap[0] = heap[heapSize - 1];
heapSize--;
HeapUtils.maxHeapify(heap, 0, heapSize);
return maxElement;
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/simplestructures/Queue.java
================================================
package org.intelligentjava.algos.simplestructures;
import org.intelligentjava.algos.trees.exceptions.QueueOverflowException;
/**
* Simple queue.
*
* @author Ignas Lelys
* @created May 4, 2011
*
*/
public class Queue {
private Object[] queue;
private int head = 0;
private int tail = 0;
public Queue() {
super();
queue = new Object[10];
}
public Queue(int queueSize) {
super();
queue = new Object[queueSize];
}
public void enqueue(Object element) throws QueueOverflowException {
if (isFull()) {
throw new QueueOverflowException();
}
queue[tail] = element;
if (tail == queue.length - 1) {
tail = 0;
} else {
tail++;
}
}
public Object dequeue() {
Object element = queue[head];
if (head == queue.length - 1) {
head = 0;
} else {
head++;
}
return element;
}
public boolean isEmpty() {
return head == tail;
}
public boolean isFull() {
int nextTailValue = tail;
if (nextTailValue == queue.length - 1) {
nextTailValue = 0;
} else {
nextTailValue++;
}
if (head == nextTailValue) {
return true;
} else {
return false;
}
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/simplestructures/Stack.java
================================================
package org.intelligentjava.algos.simplestructures;
import java.util.Arrays;
/**
* Stack.
*
* @author Ignas Lelys
* @created May 4, 2011
*
*/
public class Stack {
private Object[] elements;
private int top = 0;
public Stack() {
super();
elements = new Object[10];
}
public Stack(int initialSize) {
super();
elements = new Object[initialSize];
}
public boolean isEmpty() {
return top == 0;
}
public void push(Object element) {
if (top == elements.length) {
elements = Arrays.copyOf(elements, elements.length + 10);
}
elements[top] = element;
top++;
}
public Object pop() {
if (!isEmpty()) {
return elements[--top];
}
return null;
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/AVLTree.java
================================================
package org.intelligentjava.algos.trees;
import org.intelligentjava.algos.trees.utils.MathUtils;
/**
* AVL tree implementation.
*
* In computer science, an AVL tree is a self-balancing binary search tree, and
* it was the first such data structure to be invented.[1] In an AVL tree, the
* heights of the two child subtrees of any node differ by at most one. Lookup,
* insertion, and deletion all take O(log n) time in both the average and worst
* cases, where n is the number of nodes in the tree prior to the operation.
* Insertions and deletions may require the tree to be rebalanced by one or more
* tree rotations.
*
* @author Ignas Lelys
* @created Jun 28, 2011
*
*/
public class AVLTree extends AbstractSelfBalancingBinarySearchTree {
/**
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#insert(int)
*
* AVL tree insert method also balances tree if needed. Additional
* height parameter on node is used to track if one subtree is higher
* than other by more than one, if so AVL tree rotations is performed
* to regain balance of the tree.
*/
@Override
public Node insert(int element) {
Node newNode = super.insert(element);
rebalance((AVLNode)newNode);
return newNode;
}
/**
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#delete(int)
*/
@Override
public Node delete(int element) {
Node deleteNode = super.search(element);
if (deleteNode != null) {
Node successorNode = super.delete(deleteNode);
if (successorNode != null) {
// if replaced from getMinimum(deleteNode.right) then come back there and update heights
AVLNode minimum = successorNode.right != null ? (AVLNode)getMinimum(successorNode.right) : (AVLNode)successorNode;
recomputeHeight(minimum);
rebalance((AVLNode)minimum);
} else {
recomputeHeight((AVLNode)deleteNode.parent);
rebalance((AVLNode)deleteNode.parent);
}
return successorNode;
}
return null;
}
/**
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#createNode(int, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node)
*/
@Override
protected Node createNode(int value, Node parent, Node left, Node right) {
return new AVLNode(value, parent, left, right);
}
/**
* Go up from inserted node, and update height and balance informations if needed.
* If some node balance reaches 2 or -2 that means that subtree must be rebalanced.
*
* @param node Inserted Node.
*/
private void rebalance(AVLNode node) {
while (node != null) {
Node parent = node.parent;
int leftHeight = (node.left == null) ? -1 : ((AVLNode) node.left).height;
int rightHeight = (node.right == null) ? -1 : ((AVLNode) node.right).height;
int nodeBalance = rightHeight - leftHeight;
// rebalance (-2 means left subtree outgrow, 2 means right subtree)
if (nodeBalance == 2) {
if (node.right.right != null) {
node = (AVLNode)avlRotateLeft(node);
break;
} else {
node = (AVLNode)doubleRotateRightLeft(node);
break;
}
} else if (nodeBalance == -2) {
if (node.left.left != null) {
node = (AVLNode)avlRotateRight(node);
break;
} else {
node = (AVLNode)doubleRotateLeftRight(node);
break;
}
} else {
updateHeight(node);
}
node = (AVLNode)parent;
}
}
/**
* Rotates to left side.
*/
private Node avlRotateLeft(Node node) {
Node temp = super.rotateLeft(node);
updateHeight((AVLNode)temp.left);
updateHeight((AVLNode)temp);
return temp;
}
/**
* Rotates to right side.
*/
private Node avlRotateRight(Node node) {
Node temp = super.rotateRight(node);
updateHeight((AVLNode)temp.right);
updateHeight((AVLNode)temp);
return temp;
}
/**
* Take right child and rotate it to the right side first and then rotate
* node to the left side.
*/
protected Node doubleRotateRightLeft(Node node) {
node.right = avlRotateRight(node.right);
return avlRotateLeft(node);
}
/**
* Take right child and rotate it to the right side first and then rotate
* node to the left side.
*/
protected Node doubleRotateLeftRight(Node node) {
node.left = avlRotateLeft(node.left);
return avlRotateRight(node);
}
/**
* Recomputes height information from the node and up for all of parents. It needs to be done after delete.
*/
private void recomputeHeight(AVLNode node) {
while (node != null) {
node.height = maxHeight((AVLNode)node.left, (AVLNode)node.right) + 1;
node = (AVLNode)node.parent;
}
}
/**
* Returns higher height of 2 nodes.
*/
private int maxHeight(AVLNode node1, AVLNode node2) {
if (node1 != null && node2 != null) {
return node1.height > node2.height ? node1.height : node2.height;
} else if (node1 == null) {
return node2 != null ? node2.height : -1;
} else if (node2 == null) {
return node1 != null ? node1.height : -1;
}
return -1;
}
/**
* Updates height and balance of the node.
*
* @param node Node for which height and balance must be updated.
*/
private static final void updateHeight(AVLNode node) {
int leftHeight = (node.left == null) ? -1 : ((AVLNode) node.left).height;
int rightHeight = (node.right == null) ? -1 : ((AVLNode) node.right).height;
node.height = 1 + MathUtils.getMax(leftHeight, rightHeight);
}
/**
* Node of AVL tree has height and balance additional properties. If balance
* equals 2 (or -2) that node needs to be re balanced. (Height is height of
* the subtree starting with this node, and balance is difference between
* left and right nodes heights).
*
* @author Ignas Lelys
* @created Jun 30, 2011
*
*/
protected static class AVLNode extends Node {
public int height;
public AVLNode(int value, Node parent, Node left, Node right) {
super(value, parent, left, right);
}
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/AbstractBinarySearchTree.java
================================================
package org.intelligentjava.algos.trees;
/**
* Abstract binary search tree implementation. Its basically fully implemented
* binary search tree, just template method is provided for creating Node (other
* trees can have slightly different nodes with more info). This way some code
* from standart binary search tree can be reused for other kinds of binary
* trees.
*
* @author Ignas Lelys
* @created Jun 29, 2011
*
*/
public abstract class AbstractBinarySearchTree {
/** Root node where whole tree starts. */
public Node root;
/** Tree size. */
protected int size;
/**
* Because this is abstract class and various trees have different additional information on
* different nodes subclasses uses this abstract method to create nodes (maybe of class {@link Node}
* or maybe some different node sub class).
*
* @param value Value that node will have.
* @param parent Node's parent.
* @param left Node's left child.
* @param right Node's right child.
* @return Created node instance.
*/
protected abstract Node createNode(int value, Node parent, Node left, Node right);
/**
* Finds a node with concrete value. If it is not found then null is
* returned.
*
* @param element
* Element value.
* @return Node with value provided, or null if not found.
*/
public Node search(int element) {
Node node = root;
while (node != null && node.value != null && node.value != element) {
if (element < node.value) {
node = node.left;
} else {
node = node.right;
}
}
return node;
}
/**
* Insert new element to tree.
*
* @param element
* Element to insert.
*/
public Node insert(int element) {
if (root == null) {
root = createNode(element, null, null, null);
size++;
return root;
}
Node insertParentNode = null;
Node searchTempNode = root;
while (searchTempNode != null && searchTempNode.value != null) {
insertParentNode = searchTempNode;
if (element < searchTempNode.value) {
searchTempNode = searchTempNode.left;
} else {
searchTempNode = searchTempNode.right;
}
}
Node newNode = createNode(element, insertParentNode, null, null);
if (insertParentNode.value > newNode.value) {
insertParentNode.left = newNode;
} else {
insertParentNode.right = newNode;
}
size++;
return newNode;
}
/**
* Removes element if node with such value exists.
*
* @param element
* Element value to remove.
*
* @return New node that is in place of deleted node. Or null if element for
* delete was not found.
*/
public Node delete(int element) {
Node deleteNode = search(element);
if (deleteNode != null) {
return delete(deleteNode);
} else {
return null;
}
}
/**
* Delete logic when node is already found.
*
* @param deleteNode
* Node that needs to be deleted.
*
* @return New node that is in place of deleted node. Or null if element for
* delete was not found.
*/
protected Node delete(Node deleteNode) {
if (deleteNode != null) {
Node nodeToReturn = null;
if (deleteNode != null) {
if (deleteNode.left == null) {
nodeToReturn = transplant(deleteNode, deleteNode.right);
} else if (deleteNode.right == null) {
nodeToReturn = transplant(deleteNode, deleteNode.left);
} else {
Node successorNode = getMinimum(deleteNode.right);
if (successorNode.parent != deleteNode) {
transplant(successorNode, successorNode.right);
successorNode.right = deleteNode.right;
successorNode.right.parent = successorNode;
}
transplant(deleteNode, successorNode);
successorNode.left = deleteNode.left;
successorNode.left.parent = successorNode;
nodeToReturn = successorNode;
}
size--;
}
return nodeToReturn;
}
return null;
}
/**
* Put one node from tree (newNode) to the place of another (nodeToReplace).
*
* @param nodeToReplace
* Node which is replaced by newNode and removed from tree.
* @param newNode
* New node.
*
* @return New replaced node.
*/
private Node transplant(Node nodeToReplace, Node newNode) {
if (nodeToReplace.parent == null) {
this.root = newNode;
} else if (nodeToReplace == nodeToReplace.parent.left) {
nodeToReplace.parent.left = newNode;
} else {
nodeToReplace.parent.right = newNode;
}
if (newNode != null) {
newNode.parent = nodeToReplace.parent;
}
return newNode;
}
/**
* @param element
* @return true if tree contains element.
*/
public boolean contains(int element) {
return search(element) != null;
}
/**
* @return Minimum element in tree.
*/
public int getMinimum() {
return getMinimum(root).value;
}
/**
* @return Maximum element in tree.
*/
public int getMaximum() {
return getMaximum(root).value;
}
/**
* Get next element element who is bigger than provided element.
*
* @param element
* Element for whom descendand element is searched
* @return Successor value.
*/
// TODO Predecessor
public int getSuccessor(int element) {
return getSuccessor(search(element)).value;
}
/**
* @return Number of elements in the tree.
*/
public int getSize() {
return size;
}
/**
* Tree traversal with printing element values. In order method.
*/
public void printTreeInOrder() {
printTreeInOrder(root);
}
/**
* Tree traversal with printing element values. Pre order method.
*/
public void printTreePreOrder() {
printTreePreOrder(root);
}
/**
* Tree traversal with printing element values. Post order method.
*/
public void printTreePostOrder() {
printTreePostOrder(root);
}
/*-------------------PRIVATE HELPER METHODS-------------------*/
private void printTreeInOrder(Node entry) {
if (entry != null) {
printTreeInOrder(entry.left);
if (entry.value != null) {
System.out.println(entry.value);
}
printTreeInOrder(entry.right);
}
}
private void printTreePreOrder(Node entry) {
if (entry != null) {
if (entry.value != null) {
System.out.println(entry.value);
}
printTreeInOrder(entry.left);
printTreeInOrder(entry.right);
}
}
private void printTreePostOrder(Node entry) {
if (entry != null) {
printTreeInOrder(entry.left);
printTreeInOrder(entry.right);
if (entry.value != null) {
System.out.println(entry.value);
}
}
}
protected Node getMinimum(Node node) {
while (node.left != null) {
node = node.left;
}
return node;
}
protected Node getMaximum(Node node) {
while (node.right != null) {
node = node.right;
}
return node;
}
protected Node getSuccessor(Node node) {
// if there is right branch, then successor is leftmost node of that
// subtree
if (node.right != null) {
return getMinimum(node.right);
} else { // otherwise it is a lowest ancestor whose left child is also
// ancestor of node
Node currentNode = node;
Node parentNode = node.parent;
while (parentNode != null && currentNode == parentNode.right) {
// go up until we find parent that currentNode is not in right
// subtree.
currentNode = parentNode;
parentNode = parentNode.parent;
}
return parentNode;
}
}
//-------------------------------- TREE PRINTING ------------------------------------
public void printTree() {
printSubtree(root);
}
public void printSubtree(Node node) {
if (node.right != null) {
printTree(node.right, true, "");
}
printNodeValue(node);
if (node.left != null) {
printTree(node.left, false, "");
}
}
private void printNodeValue(Node node) {
if (node.value == null) {
System.out.print("<null>");
} else {
System.out.print(node.value.toString());
}
System.out.println();
}
private void printTree(Node node, boolean isRight, String indent) {
if (node.right != null) {
printTree(node.right, true, indent + (isRight ? " " : " | "));
}
System.out.print(indent);
if (isRight) {
System.out.print(" /");
} else {
System.out.print(" \\");
}
System.out.print("----- ");
printNodeValue(node);
if (node.left != null) {
printTree(node.left, false, indent + (isRight ? " | " : " "));
}
}
public static class Node {
public Node(Integer value, Node parent, Node left, Node right) {
super();
this.value = value;
this.parent = parent;
this.left = left;
this.right = right;
}
public Integer value;
public Node parent;
public Node left;
public Node right;
public boolean isLeaf() {
return left == null && right == null;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/AbstractSelfBalancingBinarySearchTree.java
================================================
package org.intelligentjava.algos.trees;
/**
* Abstract class for self balancing binary search trees. Contains some methods
* that is used for self balancing trees.
*
* @author Ignas Lelys
* @created Jul 24, 2011
*
*/
public abstract class AbstractSelfBalancingBinarySearchTree extends AbstractBinarySearchTree {
/**
* Rotate to the left.
*
* @param node Node on which to rotate.
* @return Node that is in place of provided node after rotation.
*/
protected Node rotateLeft(Node node) {
Node temp = node.right;
temp.parent = node.parent;
node.right = temp.left;
if (node.right != null) {
node.right.parent = node;
}
temp.left = node;
node.parent = temp;
// temp took over node's place so now its parent should point to temp
if (temp.parent != null) {
if (node == temp.parent.left) {
temp.parent.left = temp;
} else {
temp.parent.right = temp;
}
} else {
root = temp;
}
return temp;
}
/**
* Rotate to the right.
*
* @param node Node on which to rotate.
* @return Node that is in place of provided node after rotation.
*/
protected Node rotateRight(Node node) {
Node temp = node.left;
temp.parent = node.parent;
node.left = temp.right;
if (node.left != null) {
node.left.parent = node;
}
temp.right = node;
node.parent = temp;
// temp took over node's place so now its parent should point to temp
if (temp.parent != null) {
if (node == temp.parent.left) {
temp.parent.left = temp;
} else {
temp.parent.right = temp;
}
} else {
root = temp;
}
return temp;
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/BinarySearchTree.java
================================================
package org.intelligentjava.algos.trees;
/**
* Binary search tree implementation.
*
* In computer science, a binary search tree (BST), which may sometimes also be
* called an ordered or sorted binary tree, is a node-based binary tree data
* structure which has the following properties:
*
* a) The left subtree of a node contains only nodes with keys less than the node's key. </br>
* b) The right subtree of a node contains only nodes with keys greater than the node's key. </br>
* c) Both the left and right subtrees must also be binary search trees. </br>
*
* @author Ignas Lelys
* @created May 6, 2011
*
*/
public class BinarySearchTree extends AbstractBinarySearchTree {
@Override
protected Node createNode(int value, Node parent, Node left, Node right) {
return new Node(value, parent, left, right);
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/RedBlackTree.java
================================================
package org.intelligentjava.algos.trees;
/**
* Red-Black tree implementation. From Introduction to Algorithms 3rd edition.
*
* @author Ignas Lelys
* @created May 6, 2011
*
*/
public class RedBlackTree extends AbstractSelfBalancingBinarySearchTree {
protected enum ColorEnum {
RED,
BLACK
};
protected static final RedBlackNode nilNode = new RedBlackNode(null, null, null, null, ColorEnum.BLACK);
/**
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#insert(int)
*/
@Override
public Node insert(int element) {
Node newNode = super.insert(element);
newNode.left = nilNode;
newNode.right = nilNode;
root.parent = nilNode;
insertRBFixup((RedBlackNode) newNode);
return newNode;
}
/**
* Slightly modified delete routine for red-black tree.
*
* {@inheritDoc}
*/
@Override
protected Node delete(Node deleteNode) {
Node replaceNode = null; // track node that replaces removedOrMovedNode
if (deleteNode != null && deleteNode != nilNode) {
Node removedOrMovedNode = deleteNode; // same as deleteNode if it has only one child, and otherwise it replaces deleteNode
ColorEnum removedOrMovedNodeColor = ((RedBlackNode)removedOrMovedNode).color;
if (deleteNode.left == nilNode) {
replaceNode = deleteNode.right;
rbTreeTransplant(deleteNode, deleteNode.right);
} else if (deleteNode.right == nilNode) {
replaceNode = deleteNode.left;
rbTreeTransplant(deleteNode, deleteNode.left);
} else {
removedOrMovedNode = getMinimum(deleteNode.right);
removedOrMovedNodeColor = ((RedBlackNode)removedOrMovedNode).color;
replaceNode = removedOrMovedNode.right;
if (removedOrMovedNode.parent == deleteNode) {
replaceNode.parent = removedOrMovedNode;
} else {
rbTreeTransplant(removedOrMovedNode, removedOrMovedNode.right);
removedOrMovedNode.right = deleteNode.right;
removedOrMovedNode.right.parent = removedOrMovedNode;
}
rbTreeTransplant(deleteNode, removedOrMovedNode);
removedOrMovedNode.left = deleteNode.left;
removedOrMovedNode.left.parent = removedOrMovedNode;
((RedBlackNode)removedOrMovedNode).color = ((RedBlackNode)deleteNode).color;
}
size--;
if (removedOrMovedNodeColor == ColorEnum.BLACK) {
deleteRBFixup((RedBlackNode)replaceNode);
}
}
return replaceNode;
}
/**
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#createNode(int, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node)
*/
@Override
protected Node createNode(int value, Node parent, Node left, Node right) {
return new RedBlackNode(value, parent, left, right, ColorEnum.RED);
}
/**
* {@inheritDoc}
*/
@Override
protected Node getMinimum(Node node) {
while (node.left != nilNode) {
node = node.left;
}
return node;
}
/**
* {@inheritDoc}
*/
@Override
protected Node getMaximum(Node node) {
while (node.right != nilNode) {
node = node.right;
}
return node;
}
/**
* {@inheritDoc}
*/
@Override
protected Node rotateLeft(Node node) {
Node temp = node.right;
temp.parent = node.parent;
node.right = temp.left;
if (node.right != nilNode) {
node.right.parent = node;
}
temp.left = node;
node.parent = temp;
// temp took over node's place so now its parent should point to temp
if (temp.parent != nilNode) {
if (node == temp.parent.left) {
temp.parent.left = temp;
} else {
temp.parent.right = temp;
}
} else {
root = temp;
}
return temp;
}
/**
* {@inheritDoc}
*/
@Override
protected Node rotateRight(Node node) {
Node temp = node.left;
temp.parent = node.parent;
node.left = temp.right;
if (node.left != nilNode) {
node.left.parent = node;
}
temp.right = node;
node.parent = temp;
// temp took over node's place so now its parent should point to temp
if (temp.parent != nilNode) {
if (node == temp.parent.left) {
temp.parent.left = temp;
} else {
temp.parent.right = temp;
}
} else {
root = temp;
}
return temp;
}
/**
* Similar to original transplant() method in BST but uses nilNode instead of null.
*/
private Node rbTreeTransplant(Node nodeToReplace, Node newNode) {
if (nodeToReplace.parent == nilNode) {
this.root = newNode;
} else if (nodeToReplace == nodeToReplace.parent.left) {
nodeToReplace.parent.left = newNode;
} else {
nodeToReplace.parent.right = newNode;
}
newNode.parent = nodeToReplace.parent;
return newNode;
}
/**
* Restores Red-Black tree properties after delete if needed.
*/
private void deleteRBFixup(RedBlackNode x) {
while (x != root && isBlack(x)) {
if (x == x.parent.left) {
RedBlackNode w = (RedBlackNode)x.parent.right;
if (isRed(w)) { // case 1 - sibling is red
w.color = ColorEnum.BLACK;
((RedBlackNode)x.parent).color = ColorEnum.RED;
rotateLeft(x.parent);
w = (RedBlackNode)x.parent.right; // converted to case 2, 3 or 4
}
// case 2 sibling is black and both of its children are black
if (isBlack(w.left) && isBlack(w.right)) {
w.color = ColorEnum.RED;
x = (RedBlackNode)x.parent;
} else if (w != nilNode) {
if (isBlack(w.right)) { // case 3 sibling is black and its left child is red and right child is black
((RedBlackNode)w.left).color = ColorEnum.BLACK;
w.color = ColorEnum.RED;
rotateRight(w);
w = (RedBlackNode)x.parent.right;
}
w.color = ((RedBlackNode)x.parent).color; // case 4 sibling is black and right child is red
((RedBlackNode)x.parent).color = ColorEnum.BLACK;
((RedBlackNode)w.right).color = ColorEnum.BLACK;
rotateLeft(x.parent);
x = (RedBlackNode)root;
} else {
x.color = ColorEnum.BLACK;
x = (RedBlackNode)x.parent;
}
} else {
RedBlackNode w = (RedBlackNode)x.parent.left;
if (isRed(w)) { // case 1 - sibling is red
w.color = ColorEnum.BLACK;
((RedBlackNode)x.parent).color = ColorEnum.RED;
rotateRight(x.parent);
w = (RedBlackNode)x.parent.left; // converted to case 2, 3 or 4
}
// case 2 sibling is black and both of its children are black
if (isBlack(w.left) && isBlack(w.right)) {
w.color = ColorEnum.RED;
x = (RedBlackNode)x.parent;
} else if (w != nilNode) {
if (isBlack(w.left)) { // case 3 sibling is black and its right child is red and left child is black
((RedBlackNode)w.right).color = ColorEnum.BLACK;
w.color = ColorEnum.RED;
rotateLeft(w);
w = (RedBlackNode)x.parent.left;
}
w.color = ((RedBlackNode)x.parent).color; // case 4 sibling is black and left child is red
((RedBlackNode)x.parent).color = ColorEnum.BLACK;
((RedBlackNode)w.left).color = ColorEnum.BLACK;
rotateRight(x.parent);
x = (RedBlackNode)root;
} else {
x.color = ColorEnum.BLACK;
x = (RedBlackNode)x.parent;
}
}
}
}
private boolean isBlack(Node node) {
return node != null ? ((RedBlackNode)node).color == ColorEnum.BLACK : false;
}
private boolean isRed(Node node) {
return node != null ? ((RedBlackNode)node).color == ColorEnum.RED : false;
}
/**
* Restores Red-Black tree properties after insert if needed. Insert can
* break only 2 properties: root is red or if node is red then children must
* be black.
*/
private void insertRBFixup(RedBlackNode currentNode) {
// current node is always RED, so if its parent is red it breaks
// Red-Black property, otherwise no fixup needed and loop can terminate
while (currentNode.parent != root && ((RedBlackNode) currentNode.parent).color == ColorEnum.RED) {
RedBlackNode parent = (RedBlackNode) currentNode.parent;
RedBlackNode grandParent = (RedBlackNode) parent.parent;
if (parent == grandParent.left) {
RedBlackNode uncle = (RedBlackNode) grandParent.right;
// case1 - uncle and parent are both red
// re color both of them to black
if (((RedBlackNode) uncle).color == ColorEnum.RED) {
parent.color = ColorEnum.BLACK;
uncle.color = ColorEnum.BLACK;
grandParent.color = ColorEnum.RED;
// grandparent was recolored to red, so in next iteration we
// check if it does not break Red-Black property
currentNode = grandParent;
}
// case 2/3 uncle is black - then we perform rotations
else {
if (currentNode == parent.right) { // case 2, first rotate left
currentNode = parent;
rotateLeft(currentNode);
parent = (RedBlackNode) currentNode.parent;
}
// do not use parent
parent.color = ColorEnum.BLACK; // case 3
grandParent.color = ColorEnum.RED;
rotateRight(grandParent);
}
} else if (parent == grandParent.right) {
RedBlackNode uncle = (RedBlackNode) grandParent.left;
// case1 - uncle and parent are both red
// re color both of them to black
if (((RedBlackNode) uncle).color == ColorEnum.RED) {
parent.color = ColorEnum.BLACK;
uncle.color = ColorEnum.BLACK;
grandParent.color = ColorEnum.RED;
// grandparent was recolored to red, so in next iteration we
// check if it does not break Red-Black property
currentNode = grandParent;
}
// case 2/3 uncle is black - then we perform rotations
else {
if (currentNode == parent.left) { // case 2, first rotate right
currentNode = parent;
rotateRight(currentNode);
parent = (RedBlackNode) currentNode.parent;
}
// do not use parent
parent.color = ColorEnum.BLACK; // case 3
grandParent.color = ColorEnum.RED;
rotateLeft(grandParent);
}
}
}
// ensure root is black in case it was colored red in fixup
((RedBlackNode) root).color = ColorEnum.BLACK;
}
protected static class RedBlackNode extends Node {
public ColorEnum color;
public RedBlackNode(Integer value, Node parent, Node left, Node right, ColorEnum color) {
super(value, parent, left, right);
this.color = color;
}
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/ScapegoatTree.java
================================================
package org.intelligentjava.algos.trees;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import org.intelligentjava.algos.trees.utils.MathUtils;
/**
* Scapegoat tree non recursive implementation.
* Warning: not sure if my implementations is really correct, didn't have time to learn more about scapegoat trees.
*
* @author Ignas Lelys
* @created Jul 28, 2011
*
*/
public class ScapegoatTree extends AbstractSelfBalancingBinarySearchTree {
/** Alpha parameter. */
private double alpha = 0.57;
private int maxSize = 0;
/**
* Constructor.
*/
public ScapegoatTree() {
super();
}
/**
* Constructor.
*
* @param alpha Alpha parameter.
*/
public ScapegoatTree(double alpha) {
super();
this.alpha = alpha;
}
/**
* {@inheritDoc}
*/
@Override
public Node insert(int element) {
Node inserted = super.insert(element);
int height = getNodeHeight(inserted);
if (height > getHAlpha()) {
Node scapegoat = findScapegoatNode(inserted);
Node scapegoatParent = scapegoat.parent;
boolean scapegoatOnParentsLeft = scapegoatParent != null && scapegoatParent.left == scapegoat;
Node rebuiltSubtree = rebuildTree(getSubtreeSize(scapegoat), scapegoat);
rebuiltSubtree.parent = scapegoatParent;
if (scapegoatParent != null) {
if (scapegoatOnParentsLeft) {
scapegoatParent.left = rebuiltSubtree;
} else {
scapegoatParent.right = rebuiltSubtree;
}
}
if (scapegoat == root) {
root = rebuiltSubtree;
}
maxSize = getSize();
}
return inserted;
}
/**
* {@inheritDoc}
*/
@Override
public Node delete(int element) {
Node replaceNode = super.delete(element);
if (getSize() <= alpha * maxSize) {
root = rebuildTree(getSize(), root);
maxSize = getSize();
}
return replaceNode;
}
/**
* {@inheritDoc}
*/
@Override
protected Node createNode(int value, Node parent, Node left, Node right) {
return new Node(value, parent, left, right);
}
/**
* Finds scapegoat node which is used for rebalancing the tree.
*
* @return Scapegoat node.
*/
protected Node findScapegoatNode(Node node) {
int size = 1;
int height = 0;
int totalSize = 0;
while (node.parent != null) {
height++;
totalSize = 1 + size + getSubtreeSize(getSibling(node));
if (height > Math.floor(MathUtils.logarithm(1 / alpha, totalSize))) {
return node.parent;
}
node = node.parent;
size = totalSize;
}
return null;
}
/**
* Rebuilds unbalanced tree.
* Found this implementation much clearer and easier to make it work: https://github.com/satchamo/Scapegoat-Tree/blob/master/scapegoat.py
* Could't get implementations from pdfs to work.
*
* @param size Size of subtree.
* @param scapegoat Scapegoat is the root of subtree of {@link size} number of nodes.
*
* @return Balanced subtree.
*/
protected Node rebuildTree(int size, Node scapegoat) {
List<Node> nodes = new ArrayList<Node>();
// flatten tree without recursion
Node currentNode = scapegoat;
boolean done = false;
Stack<Node> stack = new Stack<>();
while (!done) {
if (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.left;
} else {
if (!stack.isEmpty()) {
currentNode = stack.pop();
nodes.add(currentNode);
currentNode = currentNode.right;
} else {
done = true;
}
}
}
// build tree from flattened list of nodes
return buildTree(nodes, 0, size - 1);
}
/**
* Build balanced tree from flattened tree.
*/
private Node buildTree(List<Node> nodes, int start, int end) {
int middle = (int)Math.ceil(((double)(start + end)) / 2.0);
if (start > end) {
return null;
}
// middle becomes root of subtree instead of scapegoat
Node node = nodes.get(middle);
// recursively get left and right nodes
Node leftNode = buildTree(nodes, start, middle - 1);
node.left = leftNode;
if (leftNode != null) {
leftNode.parent = node;
}
Node rightNode = buildTree(nodes, middle + 1, end);
node.right = rightNode;
if (rightNode != null) {
rightNode.parent = node;
}
return node;
}
/**
* @return Node's sibling.
*/
// TODO move to AbstractBinaySearchTree and use in other trees where needed.
private Node getSibling(Node node) {
if (node.parent != null) {
if (node.parent.left == node) {
return node.parent.right;
} else {
return node.parent.left;
}
}
return null;
}
/**
* Calculate size of subtree.
*
* @param node
* Subtree root node.
* @return Number of elements in the subtree.
*/
// TODO move to AbstractBinaySearchTree
protected int getSubtreeSize(Node node) {
if (node == null) {
return 0;
}
if (node.isLeaf()) {
return 1;
} else {
int sum = 1;
sum += getSubtreeSize(node.left);
sum += getSubtreeSize(node.right);
return sum;
}
}
// TODO move to AbstractBinaySearchTree
protected int getNodeHeight(Node node) {
if (node == null) {
return -1;
} else if (node.parent == null) {
return 0;
} else {
return getNodeHeight(node.parent) + 1;
}
}
private int getHAlpha() {
return (int)Math.floor(MathUtils.logarithm(1 / alpha, (double)getSize()));
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/SplayTree.java
================================================
package org.intelligentjava.algos.trees;
/**
* Splay tree implementation.
*
* @author Ignas Lelys
* @created Jul 19, 2011
*
*/
public class SplayTree extends AbstractSelfBalancingBinarySearchTree {
/**
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#search(int)
*/
@Override
public Node search(int element) {
Node node = super.search(element);
if (node != null) {
splay(node);
}
return node;
}
/**
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#insert(int)
*/
@Override
public Node insert(int element) {
Node insertNode = super.insert(element);
splay(insertNode);
return insertNode;
}
/**
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#delete(int)
*/
@Override
public Node delete(int element) {
// search first, because need parent to splay, might be improved later if needed
Node deleteNode = super.search(element); // do not use search with splaying
Node successor = null;
if (deleteNode != null) {
Node parent = deleteNode.parent;
successor = super.delete(deleteNode);
if (parent != null) {
splay(parent);
}
}
return successor;
}
/**
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#createNode(int, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node, org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node)
*/
@Override
protected Node createNode(int value, Node parent, Node left, Node right) {
return new Node(value, parent, left, right);
}
/**
* Splay operation. Move node to the root through some tree transformations.
*
* @param node
* Node to perform splay operation on.
*/
protected void splay(Node node) {
// move node up until its root
while (node != root) {
// Zig step
Node parent = node.parent;
if (parent.equals(root)) {
if (node.equals(parent.left)) {
rotateRight(parent);
} else if (node.equals(parent.right)) {
rotateLeft(parent);
}
break;
} else {
Node grandParent = parent.parent;
boolean nodeAndParentLeftChildren = node.equals(parent.left) && parent.equals(grandParent.left);
boolean nodeAndParentRightChildren = node.equals(parent.right) && parent.equals(grandParent.right);
boolean nodeRightChildParentLeftChild = node.equals(parent.right) && parent.equals(grandParent.left);
boolean nodeLeftChildParentRightChild = node.equals(parent.left) && parent.equals(grandParent.right);
// Zig zig step to the right
if (nodeAndParentLeftChildren) {
rotateRight(grandParent);
rotateRight(parent);
}
// Zig zig step to the left
else if (nodeAndParentRightChildren) {
rotateLeft(grandParent);
rotateLeft(parent);
}
// Zig zag steps
else if (nodeRightChildParentLeftChild) {
rotateLeft(parent);
rotateRight(grandParent);
}
else if (nodeLeftChildParentRightChild) {
rotateRight(parent);
rotateLeft(grandParent);
}
}
}
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/Treap.java
================================================
package org.intelligentjava.algos.trees;
import java.util.Random;
/**
* Treap is randomized binary search tree. Easiest way to randomize would be to get all elements in array and then after
* random permutation insert them all. However that would require to know all elements in advance. Treap solves this by
* introducing additional variable to its node - priority which is generated randomly.
*
* @author Ignas Lelys
* @created Jul 25, 2011
*
*/
public class Treap extends AbstractSelfBalancingBinarySearchTree {
private Random random = new Random(System.currentTimeMillis());
/**
* Insert same as normal binary search tree first, just TreapNode will have random number - priority. Then performs
* rotations up until root if priority of child is larger than priority of parent.
*
* @see org.intelligentjava.algos.trees.AbstractBinarySearchTree#insert(int)
*/
@Override
public Node insert(int element) {
// insert as in normal BST
TreapNode insertedNode = (TreapNode) super.insert(element);
// then rebalance by randomized priority
while (insertedNode != root) {
TreapNode parent = (TreapNode) insertedNode.parent;
if (parent.priority < insertedNode.priority) {
if (insertedNode.equals(parent.left)) {
rotateRight(parent);
} else {
rotateLeft(parent);
}
} else {
break;
}
}
return insertedNode;
}
/**
* {@inheritDoc}
*/
@Override
protected Node delete(Node deleteNode) {
if (deleteNode != null) {
// rotate node down to leaf
Node replaceNode = rotateDown((TreapNode)deleteNode);
// then delete it normally
super.delete(deleteNode);
return replaceNode;
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
protected Node createNode(int value, Node parent, Node left, Node right) {
return new TreapNode(value, parent, left, right, random.nextInt(10000));
}
/**
* Rotates a node downwards until it becomes a leaf. It must be deleted later to keep heap property intact.
*
* @param node The node which is moved to leaf.
*
* @return Node that replaces the one which is moved downwards to leaf.
*/
private Node rotateDown(TreapNode node) {
Node replaceNode = null;
while (true) {
if (node.left != null) {
boolean leftNodePriorityLarger = node.right == null || ((TreapNode) node.left).priority >= ((TreapNode) node.right).priority;
if (leftNodePriorityLarger) {
Node replace = rotateRight(node);
if (replaceNode == null) {
replaceNode = replace;
}
} else {
Node replace = rotateLeft(node);
if (replaceNode == null) {
replaceNode = replace;
}
}
} else if (node.right != null) {
Node replace = rotateLeft(node);
if (replaceNode == null) {
replaceNode = replace;
}
} else {
break;
}
}
return replaceNode;
}
/**
* Node for Treap. It has additional priority value which is set randomly. It is used for tree randomization.
*
* @author Ignas Lelys
* @created Jul 25, 2011
*/
protected static class TreapNode extends Node {
public int priority;
public TreapNode(int value, Node parent, Node left, Node right, int priority) {
super(value, parent, left, right);
this.priority = priority;
}
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesDeleteBenchmark.java
================================================
package org.intelligentjava.algos.trees.benchmark;
import java.util.Random;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import org.intelligentjava.algos.trees.AVLTree;
import org.intelligentjava.algos.trees.RedBlackTree;
import org.intelligentjava.algos.trees.ScapegoatTree;
import org.intelligentjava.algos.trees.SplayTree;
import org.intelligentjava.algos.trees.Treap;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 1, time = 1)
@Measurement(iterations = 2, time = 1)
@State(Scope.Thread)
public class TreesDeleteBenchmark {
private static final int SIZE = 100000;
private Integer[] randomInts = new Integer[SIZE];
@Setup(Level.Trial)
public void setup() {
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < SIZE; i++) {
randomInts[i] = random.nextInt(SIZE);
}
}
@Benchmark
public Object timeJDKTreeSet() {
TreeSet<Integer> treeSet = new TreeSet<>();
for (int i = 0; i < SIZE; i++) {
treeSet.add(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
treeSet.remove(randomInts[i]);
}
return treeSet.contains(randomInts[0]);
}
@Benchmark
public Object timeDeleteRedBlackTree() {
RedBlackTree rbTree = new RedBlackTree();
for (int i = 0; i < SIZE; i++) {
rbTree.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
rbTree.delete(randomInts[i]);
}
return rbTree.root;
}
@Benchmark
public Object timeDeleteAVLTree() {
AVLTree avlTree = new AVLTree();
for (int i = 0; i < SIZE; i++) {
avlTree.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
avlTree.delete(randomInts[i]);
}
return avlTree.root;
}
@Benchmark
public Object timeDeleteSplayTree() {
SplayTree splayTree = new SplayTree();
for (int i = 0; i < SIZE; i++) {
splayTree.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
splayTree.delete(randomInts[i]);
}
return splayTree.root;
}
@Benchmark
public Object timeDeleteTreap() {
Treap treap = new Treap();
for (int i = 0; i < SIZE; i++) {
treap.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
treap.delete(randomInts[i]);
}
return treap.root;
}
@Benchmark
public Object timeDeleteScapegoat0_6Tree() {
ScapegoatTree scapegoatTree0_6 = new ScapegoatTree(0.6);
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_6.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_6.delete(randomInts[i]);
}
return scapegoatTree0_6.root;
}
@Benchmark
public Object timeDeleteScapegoat0_75Tree() {
ScapegoatTree scapegoatTree0_75 = new ScapegoatTree(0.75);
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_75.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_75.delete(randomInts[i]);
}
return scapegoatTree0_75.root;
}
@Benchmark
public Object timeDeleteScapegoat0_9Tree() {
ScapegoatTree scapegoatTree0_9 = new ScapegoatTree(0.9);
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_9.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_9.delete(randomInts[i]);
}
return scapegoatTree0_9.root;
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder().include(".*" + TreesDeleteBenchmark.class.getSimpleName() + ".*").forks(1)
.build();
new Runner(opt).run();
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesInsertRandomBenchmark.java
================================================
package org.intelligentjava.algos.trees.benchmark;
import java.util.Random;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import org.intelligentjava.algos.trees.AVLTree;
import org.intelligentjava.algos.trees.RedBlackTree;
import org.intelligentjava.algos.trees.ScapegoatTree;
import org.intelligentjava.algos.trees.SplayTree;
import org.intelligentjava.algos.trees.Treap;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 1, time = 1)
@Measurement(iterations = 2, time = 1)
@State(Scope.Thread)
public class TreesInsertRandomBenchmark {
private static final int SIZE = 100000;
private Integer[] randomInts = new Integer[SIZE];
@Setup(Level.Trial)
public void setup() {
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < SIZE; i++) {
randomInts[i] = random.nextInt(SIZE);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Benchmark
public Object timeJDKTreeSet() {
TreeSet tree = new TreeSet();
for (int i = 0; i < SIZE; i++) {
tree.add(randomInts[i]);
}
return tree.contains(Integer.MAX_VALUE);
}
@Benchmark
public Object timeRedBlackTree() {
RedBlackTree tree = new RedBlackTree();
for (int i = 0; i < SIZE; i++) {
tree.insert(randomInts[i]);
}
return tree.root;
}
@Benchmark
public Object timeAVLTree() {
AVLTree tree = new AVLTree();
for (int i = 0; i < SIZE; i++) {
tree.insert(randomInts[i]);
}
return tree.root;
}
@Benchmark
public Object timeSplayTree() {
SplayTree tree = new SplayTree();
for (int i = 0; i < SIZE; i++) {
tree.insert(randomInts[i]);
}
return tree.root;
}
@Benchmark
public Object timeTreap() {
Treap tree = new Treap();
for (int i = 0; i < SIZE; i++) {
tree.insert(randomInts[i]);
}
return tree.root;
}
@Benchmark
public Object timeScapegoat0_6Tree() {
ScapegoatTree tree = new ScapegoatTree(0.6);
for (int i = 0; i < SIZE; i++) {
tree.insert(randomInts[i]);
}
return tree.root;
}
@Benchmark
public Object timeScapegoat0_75Tree() {
ScapegoatTree tree = new ScapegoatTree(0.75);
for (int i = 0; i < SIZE; i++) {
tree.insert(randomInts[i]);
}
return tree.root;
}
@Benchmark
public Object timeScapegoat0_9Tree() {
ScapegoatTree tree = new ScapegoatTree(0.9);
for (int i = 0; i < SIZE; i++) {
tree.insert(randomInts[i]);
}
return tree.root;
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder().include(".*" + TreesInsertRandomBenchmark.class.getSimpleName() + ".*").forks(1)
.build();
new Runner(opt).run();
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesInsertSortedBenchmark.java
================================================
package org.intelligentjava.algos.trees.benchmark;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import org.intelligentjava.algos.trees.AVLTree;
import org.intelligentjava.algos.trees.RedBlackTree;
import org.intelligentjava.algos.trees.ScapegoatTree;
import org.intelligentjava.algos.trees.SplayTree;
import org.intelligentjava.algos.trees.Treap;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 1, time = 1)
@Measurement(iterations = 2, time = 1)
@State(Scope.Thread)
public class TreesInsertSortedBenchmark {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Benchmark
public Object timeJDKTreeSet() {
TreeSet tree = new TreeSet();
for (int i = 0; i < 100000; i++) {
tree.add(i);
}
return tree.contains(Integer.MAX_VALUE);
}
@Benchmark
public Object timeRedBlackTree() {
RedBlackTree tree = new RedBlackTree();
for (int i = 0; i < 100000; i++) {
tree.insert(i);
}
return tree.root;
}
@Benchmark
public Object timeAVLTree() {
AVLTree tree = new AVLTree();
for (int i = 0; i < 100000; i++) {
tree.insert(i);
}
return tree.root;
}
@Benchmark
public Object timeSplayTree() {
SplayTree tree = new SplayTree();
for (int i = 0; i < 100000; i++) {
tree.insert(i);
}
return tree.root;
}
@Benchmark
public Object timeTreap() {
Treap tree = new Treap();
for (int i = 0; i < 100000; i++) {
tree.insert(i);
}
return tree.root;
}
@Benchmark
public Object timeScapegoat0_6Tree() {
ScapegoatTree tree = new ScapegoatTree(0.6);
for (int i = 0; i < 100000; i++) {
tree.insert(i);
}
return tree.root;
}
@Benchmark
public Object timeScapegoat0_75Tree() {
ScapegoatTree tree = new ScapegoatTree(0.75);
for (int i = 0; i < 100000; i++) {
tree.insert(i);
}
return tree.root;
}
@Benchmark
public Object timeScapegoat0_9Tree() {
ScapegoatTree tree = new ScapegoatTree(0.9);
for (int i = 0; i < 100000; i++) {
tree.insert(i);
}
return tree.root;
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder().include(".*" + TreesInsertSortedBenchmark.class.getSimpleName() + ".*").forks(1)
.build();
new Runner(opt).run();
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesSearchBenchmark.java
================================================
package org.intelligentjava.algos.trees.benchmark;
import java.util.Random;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import org.intelligentjava.algos.trees.AVLTree;
import org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;
import org.intelligentjava.algos.trees.RedBlackTree;
import org.intelligentjava.algos.trees.ScapegoatTree;
import org.intelligentjava.algos.trees.SplayTree;
import org.intelligentjava.algos.trees.Treap;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
@SuppressWarnings("unchecked")
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 1, time = 1)
@Measurement(iterations = 2, time = 1)
@State(Scope.Thread)
public class TreesSearchBenchmark {
private static final int SIZE = 100000;
@SuppressWarnings("rawtypes")
private TreeSet treeSet = new TreeSet();
private RedBlackTree rbTree = new RedBlackTree();
private AVLTree avlTree = new AVLTree();
private SplayTree splayTree = new SplayTree();
private Treap treap = new Treap();
private ScapegoatTree scapegoatTree0_6 = new ScapegoatTree(0.6);
private ScapegoatTree scapegoatTree0_75 = new ScapegoatTree(0.75);
private ScapegoatTree scapegoatTree0_9 = new ScapegoatTree(0.9);
private Integer[] randomInts = new Integer[SIZE];
@Setup(Level.Trial)
public void setup() {
Random random = new Random(System.currentTimeMillis());
for (Integer i = 0; i < SIZE; i++) {
randomInts[i] = random.nextInt(SIZE);
}
for (int i = 0; i < SIZE; i++) {
rbTree.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
treeSet.add(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
avlTree.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
splayTree.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
treap.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_6.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_75.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_9.insert(randomInts[i]);
}
}
@Benchmark
public boolean timeJDKTreeSet() {
boolean[] booleans = new boolean[SIZE];
for (int i = 0; i < SIZE; i++) {
booleans[i] = treeSet.contains(randomInts[i]);
}
return booleans[0];
}
@Benchmark
public Node timeSearchRedBlackTree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = rbTree.search(randomInts[i]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchAVLTree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = avlTree.search(randomInts[i]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchSplayTree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = splayTree.search(randomInts[i]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchTreap() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = treap.search(randomInts[i]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchScapegoat0_6Tree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = scapegoatTree0_6.search(randomInts[i]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchScapegoat0_75Tree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = scapegoatTree0_75.search(randomInts[i]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchScapegoat0_9Tree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = scapegoatTree0_9.search(randomInts[i]);
}
return nodes[0];
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder().include(".*" + TreesDeleteBenchmark.class.getSimpleName() + ".*").forks(1)
.build();
new Runner(opt).run();
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesSearchSameElementsBenchmark.java
================================================
package org.intelligentjava.algos.trees.benchmark;
import java.util.Random;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import org.intelligentjava.algos.trees.AVLTree;
import org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;
import org.intelligentjava.algos.trees.RedBlackTree;
import org.intelligentjava.algos.trees.ScapegoatTree;
import org.intelligentjava.algos.trees.SplayTree;
import org.intelligentjava.algos.trees.Treap;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
@SuppressWarnings("unchecked")
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 1, time = 1)
@Measurement(iterations = 3, time = 1)
@State(Scope.Thread)
public class TreesSearchSameElementsBenchmark {
private static final int SIZE = 100000;
@SuppressWarnings("rawtypes")
private TreeSet treeSet = new TreeSet();
private RedBlackTree rbTree = new RedBlackTree();
private AVLTree avlTree = new AVLTree();
private SplayTree splayTree = new SplayTree();
private Treap treap = new Treap();
private ScapegoatTree scapegoatTree0_6 = new ScapegoatTree(0.6);
private ScapegoatTree scapegoatTree0_75 = new ScapegoatTree(0.75);
private ScapegoatTree scapegoatTree0_9 = new ScapegoatTree(0.9);
private Integer[] randomInts = new Integer[SIZE];
@Setup(Level.Trial)
public void setup() {
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < SIZE; i++) {
randomInts[i] = random.nextInt(SIZE);
}
for (int i = 0; i < SIZE; i++) {
rbTree.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
treeSet.add(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
avlTree.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
splayTree.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
treap.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_6.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_75.insert(randomInts[i]);
}
for (int i = 0; i < SIZE; i++) {
scapegoatTree0_9.insert(randomInts[i]);
}
}
@Benchmark
public boolean timeJDKTreeSet() {
boolean[] booleans = new boolean[SIZE];
for (int i = 0; i < SIZE; i++) {
booleans[i] = treeSet.contains(randomInts[i % 100]);
}
return booleans[0];
}
@Benchmark
public Node timeSearchRedBlackTree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = rbTree.search(randomInts[i % 100]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchAVLTree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = avlTree.search(randomInts[i % 100]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchSplayTree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = splayTree.search(randomInts[i % 100]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchTreap() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = treap.search(randomInts[i % 100]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchScapegoat0_6Tree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = scapegoatTree0_6.search(randomInts[i % 100]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchScapegoat0_75Tree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = scapegoatTree0_75.search(randomInts[i % 100]);
}
return nodes[0];
}
@Benchmark
public Node timeSearchScapegoat0_9Tree() {
Node[] nodes = new Node[SIZE];
for (int i = 0; i < SIZE; i++) {
nodes[i] = scapegoatTree0_9.search(randomInts[i % 100]);
}
return nodes[0];
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder().include(".*" + TreesDeleteBenchmark.class.getSimpleName() + ".*").forks(1)
.build();
new Runner(opt).run();
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/exceptions/QueueOverflowException.java
================================================
package org.intelligentjava.algos.trees.exceptions;
/**
* Exception when queue overflow.
*
* @author Ignas Lelys
* @created May 4, 2011
*
*/
public class QueueOverflowException extends Exception {
private static final long serialVersionUID = 1L;
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/main/Main.java
================================================
package org.intelligentjava.algos.trees.main;
import java.util.Random;
import org.intelligentjava.algos.trees.RedBlackTree;
public class Main {
private static final int SIZE = 100;
public static void main(String[] args) {
Random random = new Random(System.currentTimeMillis());
Integer[] randomInts = new Integer[SIZE];
for (int i = 0; i < SIZE; i++) {
randomInts[i] = random.nextInt(SIZE);
}
long currentTimeMillis = System.currentTimeMillis();
RedBlackTree tree = new RedBlackTree();
for (int i = 1; i < SIZE; i++) {
tree.insert(randomInts[i]);
}
for (int i = 1; i < SIZE / 2; i++) {
tree.delete(randomInts[i]);
}
tree.printTree();
System.out.println(System.currentTimeMillis() - currentTimeMillis + " ms");
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/utils/ArrayUtils.java
================================================
package org.intelligentjava.algos.trees.utils;
/**
* Helper class which helps to work with arrays.
*
* @author Ignas Lelys
* @created Apr 18, 2011
*
*/
public class ArrayUtils {
/**
* Swaps elements in array.
*
* @param data
* Array of elements.
* @param elementIndex1
* Index of element which value will be moved to elementIndex2.
* @param elementIndex2
* Index of element which value will be moved to elementIndex1.
*/
public static void swap(int[] data, int elementIndex1, int elementIndex2) {
int tmp = data[elementIndex1];
data[elementIndex1] = data[elementIndex2];
data[elementIndex2] = tmp;
}
/**
* Select nth smallest element in array. It could be easily solved by
* sorting array and select nth element, but this algorithm is more
* efficient. Expected running time is O(n). However worst case scenario
* could be O(n^2).
*
* @param data Data array.
* @param n N parameter.
* @return Value of nth smallest element.
*/
public static int selectNthSmallestElement(int[] data, int n) {
return selectNthSmallestElement(data, 0, data.length - 1, n);
}
/**
* Select nth smallest element in array from sublist.
*
* @param @param data Data array.
* @param sublistStartIndex Sublist start index.
* @param sublistEndIndex Sublist end index.
* @param n N parameter.
* @return Value of nth smallest element in sublist.
*/
public static int selectNthSmallestElement(int[] data, int sublistStartIndex, int sublistEndIndex, int n) {
if (sublistStartIndex == sublistEndIndex) {
return data[sublistStartIndex];
}
int pivotIndex = partition(data, sublistStartIndex, sublistEndIndex);
int k = sublistStartIndex - pivotIndex + 1;
if (n == k) {
return data[pivotIndex];
} else if (n < k) {
return selectNthSmallestElement(data, sublistStartIndex, pivotIndex - 1, n);
} else {
return selectNthSmallestElement(data, pivotIndex, sublistEndIndex, n - k);
}
}
/**
* Partition algorithm.
*
* @param @param data Data array.
* @param sublistStartIndex Sublist start index.
* @param sublistEndIndex Sublist end index.
* @return Pivot index.
*/
private static int partition(int[] data, int sublistStartIndex, int sublistEndIndex) {
int pivotElement = data[sublistEndIndex];
int pivotIndex = sublistStartIndex - 1;
for (int i = sublistStartIndex; i < sublistEndIndex; i++) {
if (data[i] <= pivotElement) {
pivotIndex++;
ArrayUtils.swap(data, pivotIndex, i);
}
}
ArrayUtils.swap(data, pivotIndex + 1, sublistEndIndex);
return pivotIndex + 1;
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/utils/HeapUtils.java
================================================
package org.intelligentjava.algos.trees.utils;
/**
* Utils for working with heap data structure. Heap is a tree like data
* structure, which has root element always bigger than its children.
* Example of a heap:
* 100
* /\
* 90 23
* /\ /
* 45 1 15
* Heap is used in heap sort and priority queues implementations.
*/
public class HeapUtils {
/**
* @param data
* @param index
*/
public static void buildMaxHeap(int[] data) {
for (int i = data.length/2; i >= 0; i--) {
maxHeapify(data, i);
}
}
/**
* This method takes array and index of root element (of heap subtree). It
* assumes that this element might not
*
* @param data
* @param index
*/
public static void maxHeapify(int[] data, int index) {
maxHeapify(data, index, data.length);
}
/**
* @param data
* @param index
* @param heapSize
*/
public static void maxHeapify(int[] data, int index, int heapSize) {
int leftLeaf = getLeftLeaf(index);
int rightLeaf = getRightLeaf(index);
int largest = index;
if (leftLeaf < heapSize && data[leftLeaf] > data[largest]) {
largest = leftLeaf;
}
if (rightLeaf < heapSize && data[rightLeaf] > data[largest]) {
largest = rightLeaf;
}
if (largest != index) {
ArrayUtils.swap(data, index, largest);
HeapUtils.maxHeapify(data, largest, heapSize);
}
}
public static int getParent(int leafIndex) {
return leafIndex / 2;
}
/**
* Calculates index of left child node.
*
* @param parentIndex
* Array index that represents parent node.
* @return Left child node index in array.
*/
private static int getLeftLeaf(int parentIndex) {
return 2 * parentIndex+1;
}
/**
* Calculates index of right child node.
*
* @param parentIndex
* Array index that represents parent node.
* @return Right child node index in array.
*/
private static int getRightLeaf(int parentIndex) {
return 2 * parentIndex + 2;
}
}
================================================
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/utils/MathUtils.java
================================================
package org.intelligentjava.algos.trees.utils;
/**
* Some syntactic sugar for math operations.
*
* @author Ignas Lelys
* @created May 3, 2011
*
*/
public class MathUtils {
/**
* Extracts digit from integer number.
*
* @param number Number from which digit is extracted.
* @param digitIndex index of digit to get. 0 - last one.
*
* @return Required digit.
*/
public static int getDigitFromNumber(int number, int digitIndex) {
// TODO error check and efficiency (maybe put powers of 10 to array)
return number / (int)Math.pow(10, digitIndex) % 10;
}
/**
* Returns bigger integer.
*
* @param first First number.
* @param second Second number.
* @return Bigger number.
*/
public static int getMax(int first, int second) {
return first > second ? first : second;
}
/**
* Calculates logarithm.
*/
public static double logarithm(double base, double a) {
return Math.log(a) / Math.log(base);
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/simplestructures/LinkedListTest.java
================================================
package org.intelligentjava.algos.simplestructures;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Ignas Lelys
* @created May 5, 2011
*
*/
public class LinkedListTest {
@Test
public void testInsertDelete() {
LinkedList list = new LinkedList();
list.insert(1);
list.insert(2);
list.insert(3);
list.insert(4);
list.insert(5);
Assert.assertEquals(list.get(0), 5);
Assert.assertEquals(list.get(1), 4);
Assert.assertEquals(list.get(2), 3);
Assert.assertEquals(list.get(3), 2);
Assert.assertEquals(list.get(4), 1);
list.delete(5);
Assert.assertEquals(list.get(0), 4);
Assert.assertEquals(list.get(1), 3);
Assert.assertEquals(list.get(2), 2);
Assert.assertEquals(list.get(3), 1);
list.delete(1);
Assert.assertEquals(list.get(0), 4);
Assert.assertEquals(list.get(1), 3);
Assert.assertEquals(list.get(2), 2);
list.delete(3);
Assert.assertEquals(list.get(0), 4);
Assert.assertEquals(list.get(1), 2);
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/simplestructures/PriorityQueueTest.java
================================================
package org.intelligentjava.algos.simplestructures;
/**
* @author Ignas Lelys
* @created May 4, 2011
*
*/
public class PriorityQueueTest {
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/simplestructures/QueueTest.java
================================================
package org.intelligentjava.algos.simplestructures;
import org.intelligentjava.algos.trees.exceptions.QueueOverflowException;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Ignas Lelys
* @created May 4, 2011
*
*/
public class QueueTest {
@Test
public void testEnqueueDequeue() throws QueueOverflowException {
Queue queue = new Queue();
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
Assert.assertEquals(queue.dequeue(), 1);
Assert.assertEquals(queue.dequeue(), 2);
Assert.assertEquals(queue.dequeue(), 3);
}
@Test
public void testIsEmpty() throws QueueOverflowException {
Queue queue = new Queue();
Assert.assertTrue(queue.isEmpty());
queue.enqueue(1);
Assert.assertFalse(queue.isEmpty());
}
@Test
public void testIsFull() throws QueueOverflowException {
Queue queue = new Queue();
for (int i = 0; i < 8; i++) {
queue.enqueue(i);
}
Assert.assertFalse(queue.isFull());
queue.enqueue(9);
Assert.assertTrue(queue.isFull());
queue.dequeue();
Assert.assertFalse(queue.isFull());
queue.enqueue(10);
Assert.assertTrue(queue.isFull());
}
// @Test(expectedExceptions = { QueueOverflowException.class })
// public void testQueueOverflow() throws QueueOverflowException {
// Queue queue = new Queue();
// for (int i = 0; i < 11; i++) {
// queue.enqueue(i);
// }
// }
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/simplestructures/StackTest.java
================================================
package org.intelligentjava.algos.simplestructures;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Ignas Lelys
* @created May 4, 2011
*
*/
public class StackTest {
@Test
public void testPushPop() {
Stack stack = new Stack();
stack.push(1);
stack.push(2);
stack.push(3);
Assert.assertEquals(stack.pop(), 3);
Assert.assertEquals(stack.pop(), 2);
Assert.assertEquals(stack.pop(), 1);
}
@Test
public void testIsEmpty() {
Stack stack = new Stack();
Assert.assertTrue(stack.isEmpty());
stack.push(1);
Assert.assertFalse(stack.isEmpty());
}
/**
* Inserts more than 10 elements to stack. (Tests if inner array grows
* correctly because starting size for it is 10 elements).
*/
@Test
public void testMoreThan10() {
Stack stack = new Stack();
for (int i = 0; i < 100; i++) {
stack.push(i);
}
for (int i = 99; i >= 0; i--) {
Assert.assertEquals(stack.pop(), i);
}
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/AVLTreeTest.java
================================================
package org.intelligentjava.algos.trees;
import org.intelligentjava.algos.trees.AVLTree.AVLNode;
import org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;
import org.junit.Assert;
import org.junit.Test;
/**
* Tests for AVL tree.
*
* @author Ignas Lelys
* @created Jun 29, 2011
*
*/
public class AVLTreeTest extends BaseBSTTest {
@Test
public void testDelete() {
AVLTree tree = new AVLTree();
tree.insert(20);
tree.insert(15);
tree.insert(25);
tree.insert(23);
Assert.assertEquals(tree.size, 4);
tree.delete(15); // root is now unbalanced rotation performed
Assert.assertEquals(tree.size, 3);
Assert.assertEquals(tree.root.value, (Integer)23); // new root
Assert.assertEquals(((AVLNode)tree.root).height, 1); // new root
Assert.assertEquals(tree.root.left.value, (Integer)20);
Assert.assertEquals(tree.root.right.value, (Integer)25);
testTreeBSTProperties(tree.root);
}
@Test
public void testInsert() {
AVLTree tree = new AVLTree();
tree.insert(20);
tree.insert(15);
tree.insert(25);
tree.insert(22);
tree.insert(21);
Assert.assertEquals(tree.size, 5);
Assert.assertEquals((int) tree.root.value, 20);
Assert.assertEquals((int) tree.root.left.value, 15);
AVLNode rightSubtree = (AVLNode) tree.root.right;
// rotation performed and height+balance updated
Assert.assertEquals((int) rightSubtree.value, 22);
Assert.assertEquals((int) rightSubtree.height, 1);
Assert.assertEquals((int) rightSubtree.right.value, 25);
Assert.assertEquals(((AVLNode) rightSubtree.right).height, 0);
Assert.assertEquals((int) rightSubtree.left.value, 21);
Assert.assertEquals(((AVLNode) rightSubtree.left).height, 0);
testTreeBSTProperties(tree.root);
}
@Test
public void testRotateLeft() {
Node root = new AVLNode(4, null, null, null);
Node rightChild = new AVLNode(6, root, null, null);
root.right = rightChild;
Node leftGrandChild = new AVLNode(5, rightChild, null, null);
Node rightGrandChild = new AVLNode(7, rightChild, null, null);
rightChild.left = leftGrandChild;
rightChild.right = rightGrandChild;
AVLTree tree = new AVLTree();
Node rotated = tree.rotateLeft(root);
Assert.assertEquals((int) rotated.value, 6);
Assert.assertEquals((int) rotated.left.value, 4);
Assert.assertEquals((int) rotated.right.value, 7);
Assert.assertEquals((int) rotated.left.right.value, 5);
Assert.assertNull(rotated.parent);
Assert.assertEquals(rotated.left.parent.value, rotated.value);
Assert.assertEquals(rotated.right.parent.value, rotated.value);
Assert.assertEquals(rotated.left.right.parent.value, rotated.left.value);
}
@Test
public void testRotateRight() {
Node root = new AVLNode(8, null, null, null);
Node leftChild = new AVLNode(6, root, null, null);
root.left = leftChild;
Node leftGrandChild = new AVLNode(5, leftChild, null, null);
Node rightGrandChild = new AVLNode(7, leftChild, null, null);
leftChild.left = leftGrandChild;
leftChild.right = rightGrandChild;
AVLTree tree = new AVLTree();
Node rotated = tree.rotateRight(root);
Assert.assertEquals((int) rotated.value, 6);
Assert.assertEquals((int) rotated.left.value, 5);
Assert.assertEquals((int) rotated.right.value, 8);
Assert.assertEquals((int) rotated.right.left.value, 7);
Assert.assertNull(rotated.parent);
Assert.assertEquals(rotated.left.parent.value, rotated.value);
Assert.assertEquals(rotated.right.parent.value, rotated.value);
Assert.assertEquals(rotated.right.left.parent.value, rotated.right.value);
}
@Test
public void testDoubleRotateRightLeft() {
Node root = new AVLNode(5, null, null, null);
Node rightChild = new AVLNode(8, root, null, null);
root.right = rightChild;
Node leftGrandChild = new AVLNode(7, rightChild, null, null);
Node rightGrandChild = new AVLNode(10, rightChild, null, null);
rightChild.left = leftGrandChild;
rightChild.right = rightGrandChild;
AVLTree tree = new AVLTree();
Node rotated = tree.doubleRotateRightLeft(root);
Assert.assertEquals((int) rotated.value, 7);
Assert.assertEquals((int) rotated.left.value, 5);
Assert.assertEquals((int) rotated.right.value, 8);
Assert.assertEquals((int) rotated.right.right.value, 10);
Assert.assertNull(rotated.parent);
Assert.assertEquals(rotated.left.parent.value, rotated.value);
Assert.assertEquals(rotated.right.parent.value, rotated.value);
Assert.assertEquals(rotated.right.right.parent.value, rotated.right.value);
}
@Test
public void testDoubleRotateLeftRight() {
Node root = new AVLNode(5, null, null, null);
Node leftChild = new AVLNode(3, root, null, null);
root.left = leftChild;
Node leftGrandChild = new AVLNode(1, leftChild, null, null);
Node rightGrandChild = new AVLNode(4, leftChild, null, null);
leftChild.left = leftGrandChild;
leftChild.right = rightGrandChild;
AVLTree tree = new AVLTree();
Node rotated = tree.doubleRotateLeftRight(root);
Assert.assertEquals((int) rotated.value, 4);
Assert.assertEquals((int) rotated.left.value, 3);
Assert.assertEquals((int) rotated.right.value, 5);
Assert.assertEquals((int) rotated.left.left.value, 1);
Assert.assertNull(rotated.parent);
Assert.assertEquals(rotated.left.parent.value, rotated.value);
Assert.assertEquals(rotated.right.parent.value, rotated.value);
Assert.assertEquals(rotated.left.left.parent.value, rotated.left.value);
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/BaseBSTTest.java
================================================
package org.intelligentjava.algos.trees;
import org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;
import org.junit.Assert;
/**
* Superclass that contains some basic BST tests.
*
* @author Ignas
*
*/
public class BaseBSTTest {
protected void testTreeBSTProperties(Node entry) {
if (entry != null) {
// test heap properties and BST properties
if (entry.left != null) {
Assert.assertTrue(entry.value >= entry.left.value);
}
if (entry.right != null) {
Assert.assertTrue(entry.value <= entry.right.value);
}
testTreeBSTProperties(entry.left);
testTreeBSTProperties(entry.right);
}
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/BinarySearchTreeTest.java
================================================
package org.intelligentjava.algos.trees;
import org.junit.Assert;
import org.junit.Test;
/**
* Tests for simple unbalanced binary search tree.
*
* @author Ignas Lelys
* @created May 6, 2011
*
*/
public class BinarySearchTreeTest extends BaseBSTTest {
@Test
public void testInsertDelete() {
BinarySearchTree tree = new BinarySearchTree();
tree.insert(10);
tree.insert(16);
tree.insert(1);
tree.insert(8);
Assert.assertTrue(tree.contains(10));
Assert.assertTrue(tree.contains(16));
Assert.assertTrue(tree.contains(1));
Assert.assertFalse(tree.contains(9));
tree.delete(16);
tree.delete(1);
Assert.assertFalse(tree.contains(16));
Assert.assertFalse(tree.contains(1));
testTreeBSTProperties(tree.root);
}
@Test
public void testSize() {
BinarySearchTree tree = new BinarySearchTree();
tree.insert(10);
tree.insert(16);
tree.insert(1);
Assert.assertEquals(tree.getSize(), 3);
tree.delete(16);
Assert.assertEquals(tree.getSize(), 2);
tree.delete(16);
Assert.assertEquals(tree.getSize(), 2);
}
@Test
public void testMinimumMaximum() {
BinarySearchTree tree = new BinarySearchTree();
tree.insert(10);
tree.insert(16);
tree.insert(1);
tree.insert(8);
Assert.assertEquals(tree.getMinimum(), 1);
Assert.assertEquals(tree.getMaximum(), 16);
}
@Test
public void testGetSuccessor() {
BinarySearchTree tree = new BinarySearchTree();
tree.insert(15);
tree.insert(6);
tree.insert(18);
tree.insert(17);
tree.insert(20);
tree.insert(3);
tree.insert(7);
tree.insert(2);
tree.insert(4);
tree.insert(13);
tree.insert(9);
Assert.assertEquals(tree.getSuccessor(15), 17);
Assert.assertEquals(tree.getSuccessor(13), 15);
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/RedBlackTreeTest.java
================================================
package org.intelligentjava.algos.trees;
import org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;
import org.intelligentjava.algos.trees.RedBlackTree.ColorEnum;
import org.intelligentjava.algos.trees.RedBlackTree.RedBlackNode;
import org.junit.Assert;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* Tests for Red-Black tree.
*
* @author Ignas Lelys
* @created Jul 18, 2011
*
*/
public class RedBlackTreeTest {
@Test
public void testInsertionFixupColoring() throws Exception {
RedBlackTree tree = new RedBlackTree();
Node node8 = tree.insert(8);
Node node3 = tree.insert(3);
Node node4 = tree.insert(4);
assertThat(((RedBlackNode)node3).color, equalTo(ColorEnum.RED));
assertThat(((RedBlackNode)node4).color, equalTo(ColorEnum.BLACK));
assertThat(((RedBlackNode)node8).color, equalTo(ColorEnum.RED));
}
@Test
public void testInsert() {
RedBlackTree tree = new RedBlackTree();
tree.insert(20);
tree.insert(15);
tree.insert(25);
tree.insert(10); // re color 15 and 25 to black on this insert
Assert.assertEquals(((RedBlackNode)tree.root).color, ColorEnum.BLACK);
Assert.assertEquals(((RedBlackNode)tree.search(15)).color, ColorEnum.BLACK);
Assert.assertEquals(((RedBlackNode)tree.search(25)).color, ColorEnum.BLACK);
tree.insert(17);
tree.insert(8);
Assert.assertEquals(((RedBlackNode)tree.search(15)).color, ColorEnum.RED);
Assert.assertEquals(((RedBlackNode)tree.search(10)).color, ColorEnum.BLACK);
Assert.assertEquals(((RedBlackNode)tree.search(17)).color, ColorEnum.BLACK);
Assert.assertEquals(((RedBlackNode)tree.search(8)).color, ColorEnum.RED);
tree.insert(9); // case 2/3 - rotation right, then left
Assert.assertEquals(((RedBlackNode)tree.search(10)).color, ColorEnum.RED);
Assert.assertEquals(((RedBlackNode)tree.search(8)).color, ColorEnum.RED);
Assert.assertEquals(((RedBlackNode)tree.search(9)).left.value, (Integer)8);
// TODO test other red black tree properties too
testTreeBSTProperties(tree.root);
}
@Test
public void testSimpleDelete() {
RedBlackTree tree = new RedBlackTree();
tree.insert(20);
tree.insert(15);
tree.insert(25);
tree.insert(23);
Assert.assertEquals(((RedBlackNode)tree.root).color, ColorEnum.BLACK);
Assert.assertEquals(tree.size, 4);
tree.delete(15);
Assert.assertEquals(tree.size, 3);
Assert.assertEquals(tree.root.value, (Integer)23); // new root
testTreeBSTProperties(tree.root);
}
@Test
public void testDelete() {
RedBlackTree tree = new RedBlackTree();
tree.insert(20);
tree.insert(15);
tree.insert(25);
tree.insert(23);
tree.insert(27);
Assert.assertEquals(((RedBlackNode)tree.root).color, ColorEnum.BLACK);
Assert.assertEquals(tree.size, 5);
Assert.assertEquals(tree.root.right.value, (Integer)25);
Assert.assertEquals(tree.root.right.left.value, (Integer)23);
Assert.assertEquals(((RedBlackNode)tree.root.right.left).color, ColorEnum.RED);
tree.delete(25);
Assert.assertEquals(tree.size, 4);
Assert.assertEquals(tree.root.value, (Integer)20);
Assert.assertEquals(tree.root.right.value, (Integer)27);
Assert.assertEquals(((RedBlackNode)tree.root.right).color, ColorEnum.BLACK);
Assert.assertEquals(tree.root.right.right.value, null);
Assert.assertEquals(tree.root.right.left.value, (Integer)23);
Assert.assertEquals(((RedBlackNode)tree.root.right.left).color, ColorEnum.RED);
testTreeBSTProperties(tree.root);
}
/**
* Test BST properties method for RedBlack tree. Not using the one from {@link BaseBSTTest} because RedBlack tree implementation uses nilNode instead of nulls.
*/
private void testTreeBSTProperties(Node entry) {
if (entry != RedBlackTree.nilNode) {
// test heap properties and BST properties
if (entry.left != RedBlackTree.nilNode) {
Assert.assertTrue(entry.value >= entry.left.value);
}
if (entry.right != RedBlackTree.nilNode) {
Assert.assertTrue(entry.value <= entry.right.value);
}
testTreeBSTProperties(entry.left);
testTreeBSTProperties(entry.right);
}
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/ScapegoatTreeTest.java
================================================
package org.intelligentjava.algos.trees;
import org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;
import org.junit.Assert;
import org.junit.Test;
/**
* Scapegoat tree implementation tests.
*
* @author Ignas Lelys
* @created Jul 28, 2011
*
*/
public class ScapegoatTreeTest extends BaseBSTTest {
@Test
public void testInsertSorted() {
ScapegoatTree tree = new ScapegoatTree();
tree.insert(1);
tree.insert(2);
tree.insert(3);
tree.insert(4);
tree.insert(5);
tree.insert(6);
tree.insert(7);
tree.insert(8);
tree.insert(9);
tree.insert(10);
tree.insert(11);
tree.insert(12);
tree.insert(13);
tree.insert(14);
tree.insert(15);
tree.insert(16);
tree.insert(17);
tree.insert(18);
Assert.assertEquals(18, tree.size);
Assert.assertEquals((Integer)5, tree.root.value);
testTreeBSTProperties(tree.root);
}
@Test
public void testInsertSortedDesc() {
ScapegoatTree tree = new ScapegoatTree();
tree.insert(18);
tree.insert(17);
tree.insert(16);
tree.insert(15);
tree.insert(14);
tree.insert(13);
tree.insert(12);
tree.insert(11);
tree.insert(10);
tree.insert(9);
tree.insert(8);
tree.insert(7);
tree.insert(6);
tree.insert(5);
tree.insert(4);
tree.insert(3);
tree.insert(2);
tree.insert(1);
tree.printTree();
Assert.assertEquals(18, tree.size);
Assert.assertEquals((Integer)12, tree.root.value);
testTreeBSTProperties(tree.root);
}
@Test
public void testDeleteSortedDesc() {
ScapegoatTree tree = new ScapegoatTree();
tree.insert(18);
tree.insert(17);
tree.insert(16);
tree.insert(15);
tree.insert(14);
tree.insert(13);
tree.insert(12);
tree.insert(11);
tree.insert(10);
tree.insert(9);
tree.insert(8);
tree.insert(7);
tree.insert(6);
tree.insert(5);
tree.insert(4);
tree.insert(3);
tree.insert(2);
tree.insert(1);
tree.printTree();
tree.delete(18);
tree.delete(17);
tree.delete(15);
tree.delete(14);
tree.delete(12);
tree.delete(10);
tree.delete(8);
tree.printTree();
Assert.assertEquals(11, tree.size);
Assert.assertEquals((Integer)13, tree.root.value);
testTreeBSTProperties(tree.root);
}
@Test
public void testBuildBigTree() {
ScapegoatTree tree = new ScapegoatTree(0.95);
for (int i = 0; i < 100; i++) {
tree.insert(i);
}
tree.printTree();
Assert.assertEquals(100, tree.size);
testTreeBSTProperties(tree.root);
for (int i = 0; i < 50; i++) {
tree.delete(i);
}
tree.printTree();
Assert.assertEquals(50, tree.size);
testTreeBSTProperties(tree.root);
}
@Test
public void testGetSubtreeSize() {
Node root = new Node(4, null, null, null);
Node rightChild = new Node(6, root, null, null);
root.right = rightChild;
Node leftGrandChild = new Node(5, rightChild, null, null);
Node rightGrandChild = new Node(7, rightChild, null, null);
rightChild.left = leftGrandChild;
rightChild.right = rightGrandChild;
ScapegoatTree tree = new ScapegoatTree();
Assert.assertEquals(tree.getSubtreeSize(root), 4);
}
@Test
public void testFindScapegoat() {
// TODO
}
@Test
public void testRebuildTree() {
// TODO
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/SplayTreeTest.java
================================================
package org.intelligentjava.algos.trees;
import org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;
import org.junit.Assert;
import org.junit.Test;
/**
* Splay tree unit tests.
*
* @author Ignas Lelys
* @created Jul 19, 2011
*
*/
public class SplayTreeTest extends BaseBSTTest {
@Test
public void testSearch() {
SplayTree splayTree = new SplayTree();
splayTree.insert(24);
splayTree.insert(20);
splayTree.insert(30);
splayTree.insert(39);
splayTree.insert(80);
splayTree.insert(11);
splayTree.search(24);
Assert.assertEquals(splayTree.root.value, (Integer)24);
Assert.assertEquals(splayTree.root.left.value, (Integer)11);
Assert.assertEquals(splayTree.root.left.right.value, (Integer)20);
Assert.assertEquals(splayTree.root.right.value, (Integer)80);
Assert.assertEquals(splayTree.root.right.left.value, (Integer)30);
Assert.assertEquals(splayTree.root.right.left.right.value, (Integer)39);
}
@Test
public void testInsert() {
SplayTree splayTree = new SplayTree();
splayTree.insert(24);
splayTree.insert(20);
splayTree.insert(30);
splayTree.insert(39);
splayTree.insert(80);
splayTree.insert(11);
Assert.assertEquals(splayTree.root.value, (Integer) 11);
Assert.assertEquals(splayTree.root.right.value, (Integer) 80);
Assert.assertNull(splayTree.root.right.right);
Assert.assertEquals(splayTree.root.right.left.value, (Integer) 30);
Assert.assertEquals(splayTree.root.right.left.right.value, (Integer) 39);
Assert.assertEquals(splayTree.root.right.left.left.value, (Integer) 20);
Assert.assertEquals(splayTree.root.right.left.left.right.value, (Integer) 24);
testTreeBSTProperties(splayTree.root);
}
@Test
public void testDelete() {
SplayTree splayTree = new SplayTree();
splayTree.insert(22);
splayTree.insert(11);
splayTree.insert(10);
splayTree.insert(16);
splayTree.insert(15);
splayTree.insert(14);
// test insert
Assert.assertEquals(splayTree.root.value, (Integer)14);
Assert.assertEquals(splayTree.root.left.value, (Integer)11);
Assert.assertEquals(splayTree.root.left.left.value, (Integer)10);
Assert.assertEquals(splayTree.root.right.value, (Integer)15);
Assert.assertEquals(splayTree.root.right.right.value, (Integer)16);
Assert.assertEquals(splayTree.root.right.right.right.value, (Integer)22);
splayTree.delete(16);
Assert.assertEquals(splayTree.root.value, (Integer)15);
Assert.assertEquals(splayTree.root.right.value, (Integer)22);
Assert.assertEquals(splayTree.root.left.value, (Integer)14);
Assert.assertEquals(splayTree.root.left.left.value, (Integer)11);
Assert.assertEquals(splayTree.root.left.left.left.value, (Integer)10);
splayTree.delete(22);
Assert.assertEquals(splayTree.root.value, (Integer)15);
Assert.assertNull(splayTree.root.right);
Assert.assertEquals(splayTree.root.left.value, (Integer)14);
Assert.assertEquals(splayTree.root.left.left.value, (Integer)11);
Assert.assertEquals(splayTree.root.left.left.left.value, (Integer)10);
splayTree.delete(15);
Assert.assertEquals(splayTree.root.value, (Integer)14);
Assert.assertNull(splayTree.root.right);
Assert.assertEquals(splayTree.root.left.value, (Integer)11);
Assert.assertEquals(splayTree.root.left.left.value, (Integer)10);
testTreeBSTProperties(splayTree.root);
}
@Test
public void testSplayZig() {
SplayTree splayTree = new SplayTree();
Node root = new Node(15, null, null, null);
splayTree.root = root;
Node left = new Node(10, root, null, null);
root.left = left;
splayTree.splay(left);
Assert.assertEquals(splayTree.root.value, (Integer) 10);
Assert.assertEquals(splayTree.root.right.value, (Integer) 15);
splayTree.splay(splayTree.root.right);
Assert.assertEquals(splayTree.root.value, (Integer) 15);
Assert.assertEquals(splayTree.root.left.value, (Integer) 10);
}
@Test
public void testSplayZigZig() {
SplayTree splayTree = new SplayTree();
Node root = new Node(15, null, null, null);
splayTree.root = root;
Node left = new Node(10, root, null, null);
Node leftleft = new Node(5, left, null, null);
left.left = leftleft;
root.left = left;
splayTree.splay(leftleft);
Assert.assertEquals(splayTree.root.value, (Integer) 5);
Assert.assertEquals(splayTree.root.right.value, (Integer) 10);
Assert.assertEquals(splayTree.root.right.right.value, (Integer) 15);
splayTree.splay(splayTree.root.right.right);
Assert.assertEquals(splayTree.root.value, (Integer) 15);
Assert.assertEquals(splayTree.root.left.value, (Integer) 10);
Assert.assertEquals(splayTree.root.left.left.value, (Integer) 5);
}
@Test
public void testSplayZigZag() {
SplayTree splayTree = new SplayTree();
Node root = new Node(15, null, null, null);
splayTree.root = root;
Node left = new Node(10, root, null, null);
Node leftright = new Node(12, left, null, null);
left.right = leftright;
root.left = left;
// zig zag left-right
splayTree.splay(leftright);
Assert.assertEquals(splayTree.root.value, (Integer) 12);
Assert.assertEquals(splayTree.root.right.value, (Integer) 15);
Assert.assertEquals(splayTree.root.left.value, (Integer) 10);
// zig zag from other side (right-left)
splayTree.root.right.left = new Node(13, splayTree.root.right, null, null);
splayTree.splay(splayTree.root.right.left);
Assert.assertEquals(splayTree.root.value, (Integer) 13);
Assert.assertEquals(splayTree.root.left.value, (Integer) 12);
Assert.assertEquals(splayTree.root.right.value, (Integer) 15);
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/TreapTest.java
================================================
package org.intelligentjava.algos.trees;
import org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;
import org.intelligentjava.algos.trees.Treap.TreapNode;
import org.junit.Assert;
import org.junit.Test;
/**
* Treap tests.
*
* @author Ignas Lelys
* @created Jul 26, 2011
*
*/
public class TreapTest extends BaseBSTTest {
// TODO check if after rotation other Nodes can destroy heap property (it shouldn't i think)
@Test
public void testInsert() {
Treap treap = new Treap() {
@Override
protected Node createNode(int value, Node parent, Node left, Node right) {
return new TreapNode(value, parent, left, right, Integer.MAX_VALUE); // create max integer priority instead of random
}
};
TreapNode root = new TreapNode(20, null, null, null, 100);
TreapNode rootLeft = new TreapNode(15, root, null, null, 99);
TreapNode rootRight = new TreapNode(25, root, null, null, 98);
root.left = rootLeft;
root.right = rootRight;
TreapNode rootLeftLeft = new TreapNode(14, rootLeft, null, null, 97);
TreapNode rootLeftRight = new TreapNode(17, rootLeft, null, null, 96);
rootLeft.left = rootLeftLeft;
rootLeft.right = rootLeftRight;
treap.root = root;
treap.insert(16);
// this should go to root because createNode sets highest priority
Assert.assertEquals(treap.size, 1); // because only one insert invoked (other nodes were added manually)
Assert.assertEquals(treap.root.value, (Integer) 16);
Assert.assertEquals(treap.root.right.value, (Integer) 20);
Assert.assertEquals(treap.root.right.right.value, (Integer) 25);
Assert.assertEquals(treap.root.right.left.value, (Integer) 17);
Assert.assertEquals(treap.root.left.value, (Integer) 15);
Assert.assertEquals(treap.root.left.left.value, (Integer) 14);
}
@Test
public void testDelete() {
Treap treap = new Treap();
TreapNode root = new TreapNode(20, null, null, null, 100);
TreapNode rootLeft = new TreapNode(15, root, null, null, 99);
TreapNode rootRight = new TreapNode(25, root, null, null, 98);
root.left = rootLeft;
root.right = rootRight;
TreapNode rootLeftLeft = new TreapNode(14, rootLeft, null, null, 97);
TreapNode rootLeftRight = new TreapNode(17, rootLeft, null, null, 96);
rootLeft.left = rootLeftLeft;
rootLeft.right = rootLeftRight;
treap.root = root;
Node delete = treap.delete(20);
Assert.assertEquals(delete.value, (Integer) 15);
}
@Test
public void testHeapPropertyAfterInsertAndDelete() {
Treap treap = new Treap();
treap.insert(23);
treap.insert(13);
treap.insert(56);
treap.insert(1);
treap.insert(34);
treap.insert(56);
treap.insert(33);
treap.insert(21);
treap.insert(65);
treap.insert(45);
treap.insert(76);
treap.insert(99);
treap.insert(43);
treap.insert(46);
treap.insert(77);
treap.insert(88);
treap.insert(102);
treap.insert(18);
treap.insert(123);
treap.insert(256);
treap.insert(111);
treap.insert(331);
treap.insert(2);
treap.insert(3);
treap.insert(4);
Assert.assertEquals(25, treap.size);
testTreeBSTProperties(treap.root);
testHeapProperties(treap.root);
treap.delete(1);
treap.delete(45);
treap.delete(43);
treap.delete(331);
treap.delete(3);
Assert.assertEquals(20, treap.size);
testTreeBSTProperties(treap.root);
testHeapProperties(treap.root);
}
private void testHeapProperties(Node entry) {
if (entry != null) {
// test heap properties and BST properties
if (entry.left != null) {
Assert.assertTrue(((TreapNode)entry).priority >= ((TreapNode)entry.left).priority);
}
if (entry.right != null) {
Assert.assertTrue(((TreapNode)entry).priority >= ((TreapNode)entry.right).priority);
}
testHeapProperties(entry.left);
testHeapProperties(entry.right);
}
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/utils/ArrayUtilsTest.java
================================================
package org.intelligentjava.algos.trees.utils;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Ignas Lelys
* @created May 3, 2011
*
*/
public class ArrayUtilsTest {
@Test
public void testSwap() {
int[] testArr = {1, 2, 4, 3};
ArrayUtils.swap(testArr, 2, 3);
Assert.assertEquals(testArr[0], 1);
Assert.assertEquals(testArr[1], 2);
Assert.assertEquals(testArr[2], 3);
Assert.assertEquals(testArr[3], 4);
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/utils/HeapUtilsTest.java
================================================
package org.intelligentjava.algos.trees.utils;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Ignas Lelys
* @created Apr 18, 2011
*
*/
public class HeapUtilsTest {
@Test
public void testBuildHeap() {
int[] testData = {16, 4, 10, 14, 7, 9, 3, 2, 8, 1};
int[] expectedData = {16, 14, 10, 8, 7, 9, 3, 2, 4, 1};
HeapUtils.buildMaxHeap(testData);
for (int i = 0; i < testData.length; i++) {
Assert.assertTrue(testData[i] == expectedData[i]);
}
}
@Test
public void testMaxHeapify() {
int[] testData = {16, 4, 10, 14, 7, 9, 3, 2, 8, 1};
int[] expectedData = {16, 14, 10, 8, 7, 9, 3, 2, 4, 1};
HeapUtils.maxHeapify(testData, 1);
for (int i = 0; i < testData.length; i++) {
Assert.assertTrue(testData[i] == expectedData[i]);
}
}
}
================================================
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/utils/MathUtilsTest.java
================================================
package org.intelligentjava.algos.trees.utils;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Ignas Lelys
* @created May 3, 2011
*
*/
public class MathUtilsTest {
@Test
public void testGetDigitFromNumber() {
Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 0), 5);
Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 1), 4);
Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 2), 4);
Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 3), 3);
Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 4), 3);
Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 5), 2);
Assert.assertEquals(MathUtils.getDigitFromNumber(2233445, 6), 2);
}
}
gitextract_wjyganpj/
├── .gitignore
├── LICENSE
├── README.md
└── Trees/
├── .gitignore
├── pom.xml
└── src/
├── main/
│ └── java/
│ └── org/
│ └── intelligentjava/
│ └── algos/
│ ├── simplestructures/
│ │ ├── LinkedList.java
│ │ ├── PriorityQueue.java
│ │ ├── Queue.java
│ │ └── Stack.java
│ └── trees/
│ ├── AVLTree.java
│ ├── AbstractBinarySearchTree.java
│ ├── AbstractSelfBalancingBinarySearchTree.java
│ ├── BinarySearchTree.java
│ ├── RedBlackTree.java
│ ├── ScapegoatTree.java
│ ├── SplayTree.java
│ ├── Treap.java
│ ├── benchmark/
│ │ ├── TreesDeleteBenchmark.java
│ │ ├── TreesInsertRandomBenchmark.java
│ │ ├── TreesInsertSortedBenchmark.java
│ │ ├── TreesSearchBenchmark.java
│ │ └── TreesSearchSameElementsBenchmark.java
│ ├── exceptions/
│ │ └── QueueOverflowException.java
│ ├── main/
│ │ └── Main.java
│ └── utils/
│ ├── ArrayUtils.java
│ ├── HeapUtils.java
│ └── MathUtils.java
└── test/
└── java/
└── org/
└── intelligentjava/
└── algos/
├── simplestructures/
│ ├── LinkedListTest.java
│ ├── PriorityQueueTest.java
│ ├── QueueTest.java
│ └── StackTest.java
└── trees/
├── AVLTreeTest.java
├── BaseBSTTest.java
├── BinarySearchTreeTest.java
├── RedBlackTreeTest.java
├── ScapegoatTreeTest.java
├── SplayTreeTest.java
├── TreapTest.java
└── utils/
├── ArrayUtilsTest.java
├── HeapUtilsTest.java
└── MathUtilsTest.java
SYMBOL INDEX (248 symbols across 36 files)
FILE: Trees/src/main/java/org/intelligentjava/algos/simplestructures/LinkedList.java
class LinkedList (line 11) | public class LinkedList {
method get (line 16) | public int get(int index) {
method insert (line 24) | public void insert(int element) {
method delete (line 32) | public void delete(int element) {
method search (line 46) | private Entry search(int key) {
class Entry (line 57) | private static class Entry {
method Entry (line 58) | public Entry(Entry previous, Entry next, int element) {
FILE: Trees/src/main/java/org/intelligentjava/algos/simplestructures/PriorityQueue.java
class PriorityQueue (line 13) | public class PriorityQueue {
method PriorityQueue (line 19) | public PriorityQueue() {
method insertElement (line 23) | public void insertElement(int element) {
method changeElementValue (line 29) | public void changeElementValue(int index, int newValue) {
method getElement (line 40) | public int getElement() {
method removeElement (line 44) | public int removeElement() {
FILE: Trees/src/main/java/org/intelligentjava/algos/simplestructures/Queue.java
class Queue (line 12) | public class Queue {
method Queue (line 20) | public Queue() {
method Queue (line 25) | public Queue(int queueSize) {
method enqueue (line 30) | public void enqueue(Object element) throws QueueOverflowException {
method dequeue (line 42) | public Object dequeue() {
method isEmpty (line 52) | public boolean isEmpty() {
method isFull (line 56) | public boolean isFull() {
FILE: Trees/src/main/java/org/intelligentjava/algos/simplestructures/Stack.java
class Stack (line 12) | public class Stack {
method Stack (line 18) | public Stack() {
method Stack (line 23) | public Stack(int initialSize) {
method isEmpty (line 28) | public boolean isEmpty() {
method push (line 32) | public void push(Object element) {
method pop (line 40) | public Object pop() {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/AVLTree.java
class AVLTree (line 20) | public class AVLTree extends AbstractSelfBalancingBinarySearchTree {
method insert (line 30) | @Override
method delete (line 40) | @Override
method createNode (line 62) | @Override
method rebalance (line 73) | private void rebalance(AVLNode node) {
method avlRotateLeft (line 109) | private Node avlRotateLeft(Node node) {
method avlRotateRight (line 120) | private Node avlRotateRight(Node node) {
method doubleRotateRightLeft (line 132) | protected Node doubleRotateRightLeft(Node node) {
method doubleRotateLeftRight (line 141) | protected Node doubleRotateLeftRight(Node node) {
method recomputeHeight (line 149) | private void recomputeHeight(AVLNode node) {
method maxHeight (line 159) | private int maxHeight(AVLNode node1, AVLNode node2) {
method updateHeight (line 175) | private static final void updateHeight(AVLNode node) {
class AVLNode (line 191) | protected static class AVLNode extends Node {
method AVLNode (line 194) | public AVLNode(int value, Node parent, Node left, Node right) {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/AbstractBinarySearchTree.java
class AbstractBinarySearchTree (line 14) | public abstract class AbstractBinarySearchTree {
method createNode (line 33) | protected abstract Node createNode(int value, Node parent, Node left, ...
method search (line 43) | public Node search(int element) {
method insert (line 61) | public Node insert(int element) {
method delete (line 99) | public Node delete(int element) {
method delete (line 117) | protected Node delete(Node deleteNode) {
method transplant (line 155) | private Node transplant(Node nodeToReplace, Node newNode) {
method contains (line 173) | public boolean contains(int element) {
method getMinimum (line 180) | public int getMinimum() {
method getMaximum (line 187) | public int getMaximum() {
method getSuccessor (line 199) | public int getSuccessor(int element) {
method getSize (line 206) | public int getSize() {
method printTreeInOrder (line 213) | public void printTreeInOrder() {
method printTreePreOrder (line 220) | public void printTreePreOrder() {
method printTreePostOrder (line 227) | public void printTreePostOrder() {
method printTreeInOrder (line 233) | private void printTreeInOrder(Node entry) {
method printTreePreOrder (line 243) | private void printTreePreOrder(Node entry) {
method printTreePostOrder (line 253) | private void printTreePostOrder(Node entry) {
method getMinimum (line 263) | protected Node getMinimum(Node node) {
method getMaximum (line 270) | protected Node getMaximum(Node node) {
method getSuccessor (line 277) | protected Node getSuccessor(Node node) {
method printTree (line 298) | public void printTree() {
method printSubtree (line 302) | public void printSubtree(Node node) {
method printNodeValue (line 312) | private void printNodeValue(Node node) {
method printTree (line 321) | private void printTree(Node node, boolean isRight, String indent) {
class Node (line 339) | public static class Node {
method Node (line 340) | public Node(Integer value, Node parent, Node left, Node right) {
method isLeaf (line 353) | public boolean isLeaf() {
method hashCode (line 357) | @Override
method equals (line 365) | @Override
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/AbstractSelfBalancingBinarySearchTree.java
class AbstractSelfBalancingBinarySearchTree (line 11) | public abstract class AbstractSelfBalancingBinarySearchTree extends Abst...
method rotateLeft (line 19) | protected Node rotateLeft(Node node) {
method rotateRight (line 51) | protected Node rotateRight(Node node) {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/BinarySearchTree.java
class BinarySearchTree (line 18) | public class BinarySearchTree extends AbstractBinarySearchTree {
method createNode (line 20) | @Override
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/RedBlackTree.java
class RedBlackTree (line 10) | public class RedBlackTree extends AbstractSelfBalancingBinarySearchTree {
type ColorEnum (line 12) | protected enum ColorEnum {
method insert (line 22) | @Override
method delete (line 37) | @Override
method createNode (line 79) | @Override
method getMinimum (line 87) | @Override
method getMaximum (line 98) | @Override
method rotateLeft (line 109) | @Override
method rotateRight (line 139) | @Override
method rbTreeTransplant (line 170) | private Node rbTreeTransplant(Node nodeToReplace, Node newNode) {
method deleteRBFixup (line 185) | private void deleteRBFixup(RedBlackNode x) {
method isBlack (line 249) | private boolean isBlack(Node node) {
method isRed (line 253) | private boolean isRed(Node node) {
method insertRBFixup (line 262) | private void insertRBFixup(RedBlackNode currentNode) {
class RedBlackNode (line 323) | protected static class RedBlackNode extends Node {
method RedBlackNode (line 326) | public RedBlackNode(Integer value, Node parent, Node left, Node righ...
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/ScapegoatTree.java
class ScapegoatTree (line 17) | public class ScapegoatTree extends AbstractSelfBalancingBinarySearchTree {
method ScapegoatTree (line 27) | public ScapegoatTree() {
method ScapegoatTree (line 36) | public ScapegoatTree(double alpha) {
method insert (line 44) | @Override
method delete (line 72) | @Override
method createNode (line 85) | @Override
method findScapegoatNode (line 95) | protected Node findScapegoatNode(Node node) {
method rebuildTree (line 121) | protected Node rebuildTree(int size, Node scapegoat) {
method buildTree (line 150) | private Node buildTree(List<Node> nodes, int start, int end) {
method getSibling (line 177) | private Node getSibling(Node node) {
method getSubtreeSize (line 196) | protected int getSubtreeSize(Node node) {
method getNodeHeight (line 211) | protected int getNodeHeight(Node node) {
method getHAlpha (line 221) | private int getHAlpha() {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/SplayTree.java
class SplayTree (line 10) | public class SplayTree extends AbstractSelfBalancingBinarySearchTree {
method search (line 15) | @Override
method insert (line 27) | @Override
method delete (line 37) | @Override
method createNode (line 55) | @Override
method splay (line 66) | protected void splay(Node node) {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/Treap.java
class Treap (line 14) | public class Treap extends AbstractSelfBalancingBinarySearchTree {
method insert (line 24) | @Override
method delete (line 47) | @Override
method createNode (line 62) | @Override
method rotateDown (line 74) | private Node rotateDown(TreapNode node) {
class TreapNode (line 108) | protected static class TreapNode extends Node {
method TreapNode (line 111) | public TreapNode(int value, Node parent, Node left, Node right, int ...
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesDeleteBenchmark.java
class TreesDeleteBenchmark (line 27) | @OutputTimeUnit(TimeUnit.MILLISECONDS)
method setup (line 38) | @Setup(Level.Trial)
method timeJDKTreeSet (line 46) | @Benchmark
method timeDeleteRedBlackTree (line 60) | @Benchmark
method timeDeleteAVLTree (line 74) | @Benchmark
method timeDeleteSplayTree (line 88) | @Benchmark
method timeDeleteTreap (line 102) | @Benchmark
method timeDeleteScapegoat0_6Tree (line 116) | @Benchmark
method timeDeleteScapegoat0_75Tree (line 130) | @Benchmark
method timeDeleteScapegoat0_9Tree (line 144) | @Benchmark
method main (line 158) | public static void main(String[] args) throws RunnerException {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesInsertRandomBenchmark.java
class TreesInsertRandomBenchmark (line 27) | @OutputTimeUnit(TimeUnit.MILLISECONDS)
method setup (line 38) | @Setup(Level.Trial)
method timeJDKTreeSet (line 46) | @SuppressWarnings({ "unchecked", "rawtypes" })
method timeRedBlackTree (line 56) | @Benchmark
method timeAVLTree (line 65) | @Benchmark
method timeSplayTree (line 74) | @Benchmark
method timeTreap (line 83) | @Benchmark
method timeScapegoat0_6Tree (line 92) | @Benchmark
method timeScapegoat0_75Tree (line 101) | @Benchmark
method timeScapegoat0_9Tree (line 110) | @Benchmark
method main (line 119) | public static void main(String[] args) throws RunnerException {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesInsertSortedBenchmark.java
class TreesInsertSortedBenchmark (line 24) | @OutputTimeUnit(TimeUnit.MILLISECONDS)
method timeJDKTreeSet (line 31) | @SuppressWarnings({ "unchecked", "rawtypes" })
method timeRedBlackTree (line 41) | @Benchmark
method timeAVLTree (line 50) | @Benchmark
method timeSplayTree (line 59) | @Benchmark
method timeTreap (line 68) | @Benchmark
method timeScapegoat0_6Tree (line 77) | @Benchmark
method timeScapegoat0_75Tree (line 86) | @Benchmark
method timeScapegoat0_9Tree (line 95) | @Benchmark
method main (line 104) | public static void main(String[] args) throws RunnerException {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesSearchBenchmark.java
class TreesSearchBenchmark (line 28) | @SuppressWarnings("unchecked")
method setup (line 48) | @Setup(Level.Trial)
method timeJDKTreeSet (line 81) | @Benchmark
method timeSearchRedBlackTree (line 90) | @Benchmark
method timeSearchAVLTree (line 99) | @Benchmark
method timeSearchSplayTree (line 108) | @Benchmark
method timeSearchTreap (line 117) | @Benchmark
method timeSearchScapegoat0_6Tree (line 126) | @Benchmark
method timeSearchScapegoat0_75Tree (line 135) | @Benchmark
method timeSearchScapegoat0_9Tree (line 144) | @Benchmark
method main (line 153) | public static void main(String[] args) throws RunnerException {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesSearchSameElementsBenchmark.java
class TreesSearchSameElementsBenchmark (line 28) | @SuppressWarnings("unchecked")
method setup (line 48) | @Setup(Level.Trial)
method timeJDKTreeSet (line 80) | @Benchmark
method timeSearchRedBlackTree (line 89) | @Benchmark
method timeSearchAVLTree (line 98) | @Benchmark
method timeSearchSplayTree (line 107) | @Benchmark
method timeSearchTreap (line 116) | @Benchmark
method timeSearchScapegoat0_6Tree (line 125) | @Benchmark
method timeSearchScapegoat0_75Tree (line 134) | @Benchmark
method timeSearchScapegoat0_9Tree (line 143) | @Benchmark
method main (line 152) | public static void main(String[] args) throws RunnerException {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/exceptions/QueueOverflowException.java
class QueueOverflowException (line 10) | public class QueueOverflowException extends Exception {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/main/Main.java
class Main (line 7) | public class Main {
method main (line 11) | public static void main(String[] args) {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/utils/ArrayUtils.java
class ArrayUtils (line 10) | public class ArrayUtils {
method swap (line 22) | public static void swap(int[] data, int elementIndex1, int elementInde...
method selectNthSmallestElement (line 38) | public static int selectNthSmallestElement(int[] data, int n) {
method selectNthSmallestElement (line 51) | public static int selectNthSmallestElement(int[] data, int sublistStar...
method partition (line 75) | private static int partition(int[] data, int sublistStartIndex, int su...
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/utils/HeapUtils.java
class HeapUtils (line 14) | public class HeapUtils {
method buildMaxHeap (line 20) | public static void buildMaxHeap(int[] data) {
method maxHeapify (line 33) | public static void maxHeapify(int[] data, int index) {
method maxHeapify (line 42) | public static void maxHeapify(int[] data, int index, int heapSize) {
method getParent (line 58) | public static int getParent(int leafIndex) {
method getLeftLeaf (line 69) | private static int getLeftLeaf(int parentIndex) {
method getRightLeaf (line 80) | private static int getRightLeaf(int parentIndex) {
FILE: Trees/src/main/java/org/intelligentjava/algos/trees/utils/MathUtils.java
class MathUtils (line 10) | public class MathUtils {
method getDigitFromNumber (line 20) | public static int getDigitFromNumber(int number, int digitIndex) {
method getMax (line 32) | public static int getMax(int first, int second) {
method logarithm (line 39) | public static double logarithm(double base, double a) {
FILE: Trees/src/test/java/org/intelligentjava/algos/simplestructures/LinkedListTest.java
class LinkedListTest (line 11) | public class LinkedListTest {
method testInsertDelete (line 13) | @Test
FILE: Trees/src/test/java/org/intelligentjava/algos/simplestructures/PriorityQueueTest.java
class PriorityQueueTest (line 8) | public class PriorityQueueTest {
FILE: Trees/src/test/java/org/intelligentjava/algos/simplestructures/QueueTest.java
class QueueTest (line 12) | public class QueueTest {
method testEnqueueDequeue (line 14) | @Test
method testIsEmpty (line 25) | @Test
method testIsFull (line 33) | @Test
FILE: Trees/src/test/java/org/intelligentjava/algos/simplestructures/StackTest.java
class StackTest (line 11) | public class StackTest {
method testPushPop (line 13) | @Test
method testIsEmpty (line 24) | @Test
method testMoreThan10 (line 36) | @Test
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/AVLTreeTest.java
class AVLTreeTest (line 15) | public class AVLTreeTest extends BaseBSTTest {
method testDelete (line 17) | @Test
method testInsert (line 35) | @Test
method testRotateLeft (line 58) | @Test
method testRotateRight (line 82) | @Test
method testDoubleRotateRightLeft (line 106) | @Test
method testDoubleRotateLeftRight (line 130) | @Test
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/BaseBSTTest.java
class BaseBSTTest (line 12) | public class BaseBSTTest {
method testTreeBSTProperties (line 14) | protected void testTreeBSTProperties(Node entry) {
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/BinarySearchTreeTest.java
class BinarySearchTreeTest (line 13) | public class BinarySearchTreeTest extends BaseBSTTest {
method testInsertDelete (line 15) | @Test
method testSize (line 34) | @Test
method testMinimumMaximum (line 47) | @Test
method testGetSuccessor (line 58) | @Test
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/RedBlackTreeTest.java
class RedBlackTreeTest (line 19) | public class RedBlackTreeTest {
method testInsertionFixupColoring (line 20) | @Test
method testInsert (line 31) | @Test
method testSimpleDelete (line 56) | @Test
method testDelete (line 72) | @Test
method testTreeBSTProperties (line 101) | private void testTreeBSTProperties(Node entry) {
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/ScapegoatTreeTest.java
class ScapegoatTreeTest (line 14) | public class ScapegoatTreeTest extends BaseBSTTest {
method testInsertSorted (line 17) | @Test
method testInsertSortedDesc (line 44) | @Test
method testDeleteSortedDesc (line 73) | @Test
method testBuildBigTree (line 110) | @Test
method testGetSubtreeSize (line 129) | @Test
method testFindScapegoat (line 142) | @Test
method testRebuildTree (line 147) | @Test
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/SplayTreeTest.java
class SplayTreeTest (line 14) | public class SplayTreeTest extends BaseBSTTest {
method testSearch (line 16) | @Test
method testInsert (line 34) | @Test
method testDelete (line 54) | @Test
method testSplayZig (line 91) | @Test
method testSplayZigZig (line 106) | @Test
method testSplayZigZag (line 125) | @Test
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/TreapTest.java
class TreapTest (line 15) | public class TreapTest extends BaseBSTTest {
method testInsert (line 18) | @Test
method testDelete (line 47) | @Test
method testHeapPropertyAfterInsertAndDelete (line 64) | @Test
method testHeapProperties (line 107) | private void testHeapProperties(Node entry) {
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/utils/ArrayUtilsTest.java
class ArrayUtilsTest (line 11) | public class ArrayUtilsTest {
method testSwap (line 13) | @Test
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/utils/HeapUtilsTest.java
class HeapUtilsTest (line 11) | public class HeapUtilsTest {
method testBuildHeap (line 13) | @Test
method testMaxHeapify (line 23) | @Test
FILE: Trees/src/test/java/org/intelligentjava/algos/trees/utils/MathUtilsTest.java
class MathUtilsTest (line 11) | public class MathUtilsTest {
method testGetDigitFromNumber (line 13) | @Test
Condensed preview — 41 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (140K chars).
[
{
"path": ".gitignore",
"chars": 118,
"preview": "Trees/.classpath\nTrees/.project\nTrees/.settings/org.eclipse.jdt.core.prefs\nTrees/.settings/org.eclipse.m2e.core.prefs\n"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 342,
"preview": "# BinarySearchTrees\nJava binary search trees implementations and tests: AVL Tree, Red black tree, Scapegoat tree, Splay "
},
{
"path": "Trees/.gitignore",
"chars": 9,
"preview": "/target/\n"
},
{
"path": "Trees/pom.xml",
"chars": 3998,
"preview": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocat"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/simplestructures/LinkedList.java",
"chars": 1789,
"preview": "package org.intelligentjava.algos.simplestructures;\n\n/**\n * Standard simple non circular doubly linked Linked List imple"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/simplestructures/PriorityQueue.java",
"chars": 1371,
"preview": "package org.intelligentjava.algos.simplestructures;\n\nimport org.intelligentjava.algos.trees.utils.ArrayUtils;\nimport org"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/simplestructures/Queue.java",
"chars": 1390,
"preview": "package org.intelligentjava.algos.simplestructures;\n\nimport org.intelligentjava.algos.trees.exceptions.QueueOverflowExce"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/simplestructures/Stack.java",
"chars": 842,
"preview": "package org.intelligentjava.algos.simplestructures;\n\nimport java.util.Arrays;\n\n/**\n * Stack.\n * \n * @author Ignas Lelys\n"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/AVLTree.java",
"chars": 6932,
"preview": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.utils.MathUtils;\n\n/**\n * AVL tree imple"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/AbstractBinarySearchTree.java",
"chars": 11177,
"preview": "package org.intelligentjava.algos.trees;\n\n/**\n * Abstract binary search tree implementation. Its basically fully impleme"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/AbstractSelfBalancingBinarySearchTree.java",
"chars": 1946,
"preview": "package org.intelligentjava.algos.trees;\n\n/**\n * Abstract class for self balancing binary search trees. Contains some me"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/BinarySearchTree.java",
"chars": 851,
"preview": "package org.intelligentjava.algos.trees;\n\n/**\n * Binary search tree implementation.\n * \n * In computer science, a binary"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/RedBlackTree.java",
"chars": 12770,
"preview": "package org.intelligentjava.algos.trees;\n\n/**\n * Red-Black tree implementation. From Introduction to Algorithms 3rd edit"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/ScapegoatTree.java",
"chars": 6387,
"preview": "package org.intelligentjava.algos.trees;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Stack;\n\nim"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/SplayTree.java",
"chars": 3748,
"preview": "package org.intelligentjava.algos.trees;\n\n/**\n * Splay tree implementation.\n * \n * @author Ignas Lelys\n * @created Jul 1"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/Treap.java",
"chars": 3913,
"preview": "package org.intelligentjava.algos.trees;\n\nimport java.util.Random;\n\n/**\n * Treap is randomized binary search tree. Easie"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesDeleteBenchmark.java",
"chars": 4748,
"preview": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.Random;\nimport java.util.TreeSet;\nimport java.util."
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesInsertRandomBenchmark.java",
"chars": 3692,
"preview": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.Random;\nimport java.util.TreeSet;\nimport java.util."
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesInsertSortedBenchmark.java",
"chars": 3173,
"preview": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.TreeSet;\nimport java.util.concurrent.TimeUnit;\n\nimp"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesSearchBenchmark.java",
"chars": 5100,
"preview": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.Random;\nimport java.util.TreeSet;\nimport java.util."
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/benchmark/TreesSearchSameElementsBenchmark.java",
"chars": 5155,
"preview": "package org.intelligentjava.algos.trees.benchmark;\n\nimport java.util.Random;\nimport java.util.TreeSet;\nimport java.util."
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/exceptions/QueueOverflowException.java",
"chars": 262,
"preview": "package org.intelligentjava.algos.trees.exceptions;\n\n/**\n * Exception when queue overflow.\n * \n * @author Ignas Lelys\n *"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/main/Main.java",
"chars": 876,
"preview": "package org.intelligentjava.algos.trees.main;\n\nimport java.util.Random;\n\nimport org.intelligentjava.algos.trees.RedBlack"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/utils/ArrayUtils.java",
"chars": 2946,
"preview": "package org.intelligentjava.algos.trees.utils;\n\n/**\n * Helper class which helps to work with arrays.\n * \n * @author Igna"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/utils/HeapUtils.java",
"chars": 2270,
"preview": "package org.intelligentjava.algos.trees.utils;\n\n/**\n * Utils for working with heap data structure. Heap is a tree like d"
},
{
"path": "Trees/src/main/java/org/intelligentjava/algos/trees/utils/MathUtils.java",
"chars": 1058,
"preview": "package org.intelligentjava.algos.trees.utils;\n\n/**\n * Some syntactic sugar for math operations.\n * \n * @author Ignas Le"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/simplestructures/LinkedListTest.java",
"chars": 1126,
"preview": "package org.intelligentjava.algos.simplestructures;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ign"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/simplestructures/PriorityQueueTest.java",
"chars": 147,
"preview": "package org.intelligentjava.algos.simplestructures;\n\n/**\n * @author Ignas Lelys\n * @created May 4, 2011\n *\n */\npublic cl"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/simplestructures/QueueTest.java",
"chars": 1560,
"preview": "package org.intelligentjava.algos.simplestructures;\n\nimport org.intelligentjava.algos.trees.exceptions.QueueOverflowExce"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/simplestructures/StackTest.java",
"chars": 1090,
"preview": "package org.intelligentjava.algos.simplestructures;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ign"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/AVLTreeTest.java",
"chars": 6047,
"preview": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AVLTree.AVLNode;\nimport org.intelligent"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/BaseBSTTest.java",
"chars": 747,
"preview": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport o"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/BinarySearchTreeTest.java",
"chars": 2032,
"preview": "package org.intelligentjava.algos.trees;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * Tests for simple unbal"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/RedBlackTreeTest.java",
"chars": 4637,
"preview": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport o"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/ScapegoatTreeTest.java",
"chars": 3888,
"preview": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport o"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/SplayTreeTest.java",
"chars": 6201,
"preview": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport o"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/TreapTest.java",
"chars": 4392,
"preview": "package org.intelligentjava.algos.trees;\n\nimport org.intelligentjava.algos.trees.AbstractBinarySearchTree.Node;\nimport o"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/utils/ArrayUtilsTest.java",
"chars": 492,
"preview": "package org.intelligentjava.algos.trees.utils;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ignas Le"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/utils/HeapUtilsTest.java",
"chars": 882,
"preview": "package org.intelligentjava.algos.trees.utils;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ignas Le"
},
{
"path": "Trees/src/test/java/org/intelligentjava/algos/trees/utils/MathUtilsTest.java",
"chars": 769,
"preview": "package org.intelligentjava.algos.trees.utils;\n\nimport org.junit.Assert;\nimport org.junit.Test;\n\n/**\n * @author Ignas Le"
}
]
About this extraction
This page contains the full source code of the ignl/BinarySearchTrees GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 41 files (129.1 KB), approximately 32.3k tokens, and a symbol index with 248 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.