diff --git a/.classpath b/.classpath
index 18d70f02..ee32f6f5 100644
--- a/.classpath
+++ b/.classpath
@@ -1,6 +1,8 @@
-
+
+
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..23842834
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/bin/
+/build/
+/dist/
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..3a3703f6
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,34 @@
+before_script:
+ - sudo apt-get install ant-optional
+ - export OPTS="-server -Xmx3072M"
+ - export JAVA_OPTS="${JAVA_OPTS} ${OPTS}"
+ - export ANT_OPTS="${ANT_OPTS} ${OPTS}"
+ - echo $JAVA_OPTS
+ - echo $ANT_OPTS
+
+dist: trusty
+
+language: java
+
+jdk:
+ - oraclejdk9
+ - oraclejdk8
+# - oraclejdk7
+# - oraclejdk6
+
+# - openjdk9
+ - openjdk8
+ - openjdk7
+# - openjdk6
+
+env:
+ - TEST_SUITE=run_tests
+# - TEST_SUITE=mathematics
+# - TEST_SUITE=numbers
+# - TEST_SUITE=search
+# - TEST_SUITE=sequences
+# - TEST_SUITE=strings
+# - TEST_SUITE=data_structures
+# - TEST_SUITE=sorts
+
+script: "ant $TEST_SUITE"
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000..3c921d47
--- /dev/null
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,15 @@
+
+
+
+#### By submitting this pull request I confirm I've read and complied with the below requirements.
+
+- [ ] I have read the [Contribution guidelines](CONTRIBUTING.md) and I am confident that my PR reflects them.
+- [ ] I have followed the [coding guidelines](CONTRIBUTING.md#cs) for this project.
+- [ ] My code follows the [skeleton code structure](CONTRIBUTING.md#sample).
+- [ ] This pull request has a descriptive title. For example, `Added {Algorithm/DS name} [{Language}]`, not `Update README.md` or `Added new code`.
diff --git a/README.md b/README.md
index 49b9be2c..f4d8bf3a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,220 @@
-java-algorithms-implementation
+Java : Algorithms and Data Structure 
==============================
-Algorithms and Data Structures implemented in Java
+The algorithms and data structures are implemented in Java.
+
+This is a collection of algorithms and data structures I've implemented in my academic and professional life. The code isn't optimized but is written to be correct and readable. The algorithms and data structures are tested and, unless noted, believed to be correct.
+
+## Created by Justin Wetherell
+
+* For questions use: http://groups.google.com/forum/#!forum/java-algorithms-implementation
+* Google: http://code.google.com/p/java-algorithms-implementation
+* Github: http://github.com/phishman3579/java-algorithms-implementation
+* LinkedIn: http://www.linkedin.com/in/phishman3579
+* E-mail: phishman3579@gmail.com
+* Twitter: http://twitter.com/phishman3579
+
+## Support me with a donation
+
+
+
+# What's been implemented:
+
+## Table of Contents
+- [Data Structures](#data-structures)
+- [Mathematics](#mathematics)
+- [Numbers](#numbers)
+- [Graphs](#graphs)
+- [Search](#search)
+- [Sequences](#sequences)
+- [Sorts](#sorts)
+- [String Functions](#string-functions)
+
+## Data Structures
+* [AVL Tree](src/com/jwetherell/algorithms/data_structures/AVLTree.java)
+* [B-Tree](src/com/jwetherell/algorithms/data_structures/BTree.java)
+* [Binary Heap (backed by an array or a tree)](src/com/jwetherell/algorithms/data_structures/BinaryHeap.java)
+* [Binary Search Tree](src/com/jwetherell/algorithms/data_structures/BinarySearchTree.java)
+* [Compact Suffix Trie (backed by a Patricia Trie)](src/com/jwetherell/algorithms/data_structures/CompactSuffixTrie.java)
+* [Disjoint Set](src/com/jwetherell/algorithms/data_structures/DisjointSet.java)
+* [Fenwick Tree {Binary Indexed Tree (BIT)}](src/com/jwetherell/algorithms/data_structures/FenwickTree.java)
+* [Graph](src/com/jwetherell/algorithms/data_structures/Graph.java)
+ + Undirected
+ + Directed (Digraph)
+* [Hash Array Mapped Trie (HAMT)](src/com/jwetherell/algorithms/data_structures/HashArrayMappedTrie.java)
+* [Hash Map (associative array)](src/com/jwetherell/algorithms/data_structures/HashMap.java)
+* [Interval Tree](src/com/jwetherell/algorithms/data_structures/IntervalTree.java)
+* [Implicit Key Treap](src/com/jwetherell/algorithms/data_structures/ImplicitKeyTreap.java)
+* [KD Tree (k-dimensional tree or k-d tree)](src/com/jwetherell/algorithms/data_structures/KdTree.java)
+* [List [backed by an array or a linked list]](src/com/jwetherell/algorithms/data_structures/List.java)
+* [LCP Array (Longest Common Prefix) [backed by a Suffix Array]](src/com/jwetherell/algorithms/data_structures/LCPArray.java)
+* [Matrix](src/com/jwetherell/algorithms/data_structures/Matrix.java)
+* [Patricia Trie](src/com/jwetherell/algorithms/data_structures/PatriciaTrie.java)
+* [Quad-Tree (Point-Region or MX-CIF)](src/com/jwetherell/algorithms/data_structures/QuadTree.java)
+* [Queue [backed by an array or a linked list]](src/com/jwetherell/algorithms/data_structures/Queue.java)
+* [Radix Trie (associative array) [backed by a Patricia Trie]](src/com/jwetherell/algorithms/data_structures/RadixTrie.java)
+* [Red-Black Tree](src/com/jwetherell/algorithms/data_structures/RedBlackTree.java)
+* [Segment Tree](src/com/jwetherell/algorithms/data_structures/SegmentTree.java)
+* [Skip List](src/com/jwetherell/algorithms/data_structures/SkipList.java)
+* [Splay Tree](src/com/jwetherell/algorithms/data_structures/SplayTree.java)
+* [Stack [backed by an array or a linked list]](src/com/jwetherell/algorithms/data_structures/Stack.java)
+* [Suffix Array](src/com/jwetherell/algorithms/data_structures/SuffixArray.java)
+* [Suffix Tree (Ukkonen's algorithm)](src/com/jwetherell/algorithms/data_structures/SuffixTree.java)
+* [Suffix Trie [backed by a Trie]](src/com/jwetherell/algorithms/data_structures/SuffixTrie.java)
+* [Ternary Search Tree](src/com/jwetherell/algorithms/data_structures/TernarySearchTree.java)
+* [Treap](src/com/jwetherell/algorithms/data_structures/Treap.java)
+* [Tree](src/com/jwetherell/algorithms/data_structures/Tree.java)
+* [Tree Map (associative array) [backed by an AVL Tree]](src/com/jwetherell/algorithms/data_structures/TreeMap.java)
+* [Trie](src/com/jwetherell/algorithms/data_structures/Trie.java)
+* [Trie Map (associative array) [backed by a Trie]](src/com/jwetherell/algorithms/data_structures/TrieMap.java)
+
+## Mathematics
+* [Distance](src/com/jwetherell/algorithms/mathematics/Distance.java)
+ + chebyshev
+ + euclidean
+* [Division](src/com/jwetherell/algorithms/mathematics/Division.java)
+ + using a loop
+ + using recursion
+ + using shifts and multiplication
+ + using only shifts
+ + using logarithm
+* [Multiplication](src/com/jwetherell/algorithms/mathematics/Multiplication.java)
+ + using a loop
+ + using recursion
+ + using only shifts
+ + using logarithms
+ + [Fast Fourier Transform](src/com/jwetherell/algorithms/mathematics/FastFourierTransform.java)
+* [Exponentiation](src/com/jwetherell/algorithms/mathematics/Exponentiation.java)
+ + recursive exponentiation
+ + fast recursive exponentiation
+ + fast modular recursive exponentiation
+* [Primes](src/com/jwetherell/algorithms/mathematics/Primes.java)
+ + is prime
+ + prime factorization
+ + sieve of eratosthenes
+ + Miller-Rabin test
+ + [Co-Primes (relatively prime, mutually prime)](src/com/jwetherell/algorithms/mathematics/Coprimes.java)
+ + [Greatest Common Divisor](src/com/jwetherell/algorithms/mathematics/GreatestCommonDivisor.java)
+ - using Euclid's algorithm
+ - using recursion
+* [Permutations](src/com/jwetherell/algorithms/mathematics/Permutations.java)
+ + strings
+ + numbers
+* [Modular arithmetic](src/com/jwetherell/algorithms/mathematics/Modular.java)
+ + add
+ + subtract
+ + multiply
+ + divide
+ + power
+* [Knapsack](src/com/jwetherell/algorithms/mathematics/Knapsack.java)
+* [Ramer Douglas Peucker](src/com/jwetherell/algorithms/mathematics/RamerDouglasPeucker.java)
+
+## Numbers
+* [Integers](src/com/jwetherell/algorithms/numbers/Integers.java)
+ + to binary String
+ - using divide and modulus
+ - using right shift and modulus
+ - using BigDecimal
+ - using divide and double
+ + is a power of 2
+ - using a loop
+ - using recursion
+ - using logarithm
+ - using bits
+ + to English (e.g. 1 would return "one")
+* [Longs](src/com/jwetherell/algorithms/numbers/Longs.java)
+ + to binary String
+ - using divide and modulus
+ - using right shift and modulus
+ - using BigDecimal
+* [Complex](src/com/jwetherell/algorithms/numbers/Complex.java)
+ + addition
+ + subtraction
+ + multiplication
+ + absolute value
+ + polar value
+
+## Graphs
+* Find shortest path(s) in a Graph from a starting Vertex
+ - [Dijkstra's algorithm (non-negative weight graphs)](src/com/jwetherell/algorithms/graph/Dijkstra.java)
+ - [Bellman-Ford algorithm (negative and positive weight graphs)](src/com/jwetherell/algorithms/graph/BellmanFord.java)
+* Find minimum spanning tree
+ - [Prim's (undirected graphs)](src/com/jwetherell/algorithms/graph/Prim.java)
+ - [Kruskal's (undirected graphs)](src/com/jwetherell/algorithms/graph/Kruskal.java)
+* Find all pairs shortest path
+ - [Johnsons's algorithm (negative and positive weight graphs)](src/com/jwetherell/algorithms/graph/Johnsons.java)
+ - [Floyd-Warshall (negative and positive weight graphs)](src/com/jwetherell/algorithms/graph/FloydWarshall.java)
+* [Cycle detection](src/com/jwetherell/algorithms/graph/CycleDetection.java)
+ - Depth first search while keeping track of visited Verticies
+ - [Connected Components](src/com/jwetherell/algorithms/graph/ConnectedComponents.java)
+* [Topological sort](src/com/jwetherell/algorithms/graph/TopologicalSort.java)
+* [A* path finding algorithm](src/com/jwetherell/algorithms/graph/AStar.java)
+* Maximum flow
+ - [Push-Relabel](src/com/jwetherell/algorithms/graph/PushRelabel.java)
+* Graph Traversal
+ - [Depth First Traversal](src/com/jwetherell/algorithms/graph/DepthFirstTraversal.java)
+ - [Breadth First Traversal](src/com/jwetherell/algorithms/graph/BreadthFirstTraversal.java)
+* [Edmonds Karp](src/com/jwetherell/algorithms/graph/EdmondsKarp.java)
+* Matching
+ - [Turbo Matching](src/com/jwetherell/algorithms/graph/TurboMatching.java)
+* [Lowest common ancestor in tree](src/com/jwetherell/algorithms/data_structures/Tree.java)
+
+
+## Search
+* Get index of value in array
+ + [Linear](src/com/jwetherell/algorithms/search/LinearSearch.java)
+ + [Quickselect](src/com/jwetherell/algorithms/search/QuickSelect.java)
+ + [Binary [sorted array input only]](src/com/jwetherell/algorithms/search/BinarySearch.java)
+ + [Lower bound [sorted array input only]](src/com/jwetherell/algorithms/search/LowerBound.java)
+ + [Upper bound [sorted array input only]](src/com/jwetherell/algorithms/search/UpperBound.java)
+ + Optimized binary (binary until a threashold then linear) [sorted array input only]
+ + [Interpolation [sorted array input only]](src/com/jwetherell/algorithms/search/InterpolationSearch.java)
+
+## Sequences
+* [Find longest common subsequence (dynamic programming)](src/com/jwetherell/algorithms/sequence/LongestCommonSubsequence.java)
+* [Find longest increasing subsequence (dynamic programming)](src/com/jwetherell/algorithms/sequence/LongestIncreasingSubsequence.java)
+* [Find number of times a subsequence occurs in a sequence (dynamic programming)](src/com/jwetherell/algorithms/sequence/SubsequenceCounter.java)
+* [Find i-th element in a Fibonacci sequence](src/com/jwetherell/algorithms/sequence/FibonacciSequence.java)
+ + using a loop
+ + using recursion
+ + using matrix multiplication
+ + using Binet's formula
+* [Find total of all elements in a sequence(Arithmetic Progression)](src/com/jwetherell/algorithms/sequence/ArithmeticProgression.java)
+ + using a loop
+ + using Triangular numbers
+* [Largest sum of contiguous subarray (Kadane's algorithm)](src/com/jwetherell/algorithms/sequence/LargestSumContiguousSubarray.java)
+* [Longest palindromic subsequence (dynamic programming)](src/com/jwetherell/algorithms/sequence/LongestPalindromicSubsequence.java)
+
+## Sorts
+* [American Flag Sort](src/com/jwetherell/algorithms/sorts/AmericanFlagSort.java)
+* [Bubble Sort](src/com/jwetherell/algorithms/sorts/BubbleSort.java)
+* [Counting Sort (Integers only)](src/com/jwetherell/algorithms/sorts/CountingSort.java)
+* [Heap Sort](src/com/jwetherell/algorithms/sorts/HeapSort.java)
+* [Insertion Sort](src/com/jwetherell/algorithms/sorts/InsertionSort.java)
+* [Merge Sort](src/com/jwetherell/algorithms/sorts/MergeSort.java)
+* [Quick Sort](src/com/jwetherell/algorithms/sorts/QuickSort.java)
+* [Radix Sort (Integers only)](src/com/jwetherell/algorithms/sorts/RadixSort.java)
+* [Shell's Sort](src/com/jwetherell/algorithms/sorts/ShellSort.java)
+
+## String Functions
+### [String Functions](src/com/jwetherell/algorithms/strings/StringFunctions.java)
+* Reverse characters in a string
+ + using additional storage (a String or StringBuilder)
+ + using in-place swaps
+ + using in-place XOR
+* Reverse words in a string
+ + using char swaps and additional storage (a StringBuilder)
+ + using StringTokenizer and additional (a String)
+ + using split() method and additional storage (a StringBuilder and String[])
+ + using in-place swaps
+* Is Palindrome
+ + using additional storage (a StringBuilder)
+ + using in-place symetric element compares
+* Subsets of characters in a String
+* Edit (Levenshtein) Distance of two Strings (Recursive, Iterative)
+### [Manacher's algorithm (Find the longest Palindrome)](src/com/jwetherell/algorithms/strings/Manacher.java)
+### [KMP (Knuth–Morris–Pratt) Algorithm - Length of maximal prefix-suffix for each prefix](src/com/jwetherell/algorithms/strings/KnuthMorrisPratt.java)
+### [String rotations](src/com/jwetherell/algorithms/strings/Rotation.java)
+ + Find in lexicographically minimal string rotation
+ + Find in lexicographically maximal string rotation
+
diff --git a/build.xml b/build.xml
new file mode 100644
index 00000000..b926ead8
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,148 @@
+
+
+ java-algorithms-implementation build file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CLASSPATH='${env_vars.CLASSPATH}'
+ JAVA_HOME='${env_vars.JAVA_HOME}'
+ JAVA_OPTS='${env_vars.JAVA_OPTS}'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/junit-4_4.3.1.jar b/lib/junit-4_4.3.1.jar
new file mode 100644
index 00000000..5d9ccff6
Binary files /dev/null and b/lib/junit-4_4.3.1.jar differ
diff --git a/src/com/jwetherell/algorithms/DataStructures.java b/src/com/jwetherell/algorithms/DataStructures.java
deleted file mode 100644
index 3017dcad..00000000
--- a/src/com/jwetherell/algorithms/DataStructures.java
+++ /dev/null
@@ -1,4098 +0,0 @@
-package com.jwetherell.algorithms;
-
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Formatter;
-import java.util.Iterator;
-import java.util.ListIterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.NavigableSet;
-import java.util.NoSuchElementException;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.concurrent.ConcurrentSkipListSet;
-
-import com.jwetherell.algorithms.data_structures.AVLTree;
-import com.jwetherell.algorithms.data_structures.BTree;
-import com.jwetherell.algorithms.data_structures.BinarySearchTree;
-import com.jwetherell.algorithms.data_structures.BinaryHeap;
-import com.jwetherell.algorithms.data_structures.CompactSuffixTrie;
-import com.jwetherell.algorithms.data_structures.Graph.Edge;
-import com.jwetherell.algorithms.data_structures.Graph.Vertex;
-import com.jwetherell.algorithms.data_structures.Graph;
-import com.jwetherell.algorithms.data_structures.HashArrayMappedTrie;
-import com.jwetherell.algorithms.data_structures.HashMap;
-import com.jwetherell.algorithms.data_structures.IHeap;
-import com.jwetherell.algorithms.data_structures.IList;
-import com.jwetherell.algorithms.data_structures.IMap;
-import com.jwetherell.algorithms.data_structures.IQueue;
-import com.jwetherell.algorithms.data_structures.ISet;
-import com.jwetherell.algorithms.data_structures.IStack;
-import com.jwetherell.algorithms.data_structures.ITree;
-import com.jwetherell.algorithms.data_structures.IntervalTree;
-import com.jwetherell.algorithms.data_structures.KdTree;
-import com.jwetherell.algorithms.data_structures.PatriciaTrie;
-import com.jwetherell.algorithms.data_structures.QuadTree;
-import com.jwetherell.algorithms.data_structures.RadixTrie;
-import com.jwetherell.algorithms.data_structures.RedBlackTree;
-import com.jwetherell.algorithms.data_structures.SegmentTree;
-import com.jwetherell.algorithms.data_structures.SegmentTree.DynamicSegmentTree;
-import com.jwetherell.algorithms.data_structures.SegmentTree.FlatSegmentTree;
-import com.jwetherell.algorithms.data_structures.SkipListMap;
-import com.jwetherell.algorithms.data_structures.SuffixTree;
-import com.jwetherell.algorithms.data_structures.TreeMap;
-import com.jwetherell.algorithms.data_structures.TrieMap;
-import com.jwetherell.algorithms.data_structures.List;
-import com.jwetherell.algorithms.data_structures.Matrix;
-import com.jwetherell.algorithms.data_structures.Queue;
-import com.jwetherell.algorithms.data_structures.SkipList;
-import com.jwetherell.algorithms.data_structures.SplayTree;
-import com.jwetherell.algorithms.data_structures.Stack;
-import com.jwetherell.algorithms.data_structures.SuffixTrie;
-import com.jwetherell.algorithms.data_structures.Treap;
-import com.jwetherell.algorithms.data_structures.Trie;
-import com.jwetherell.algorithms.graph.BellmanFord;
-import com.jwetherell.algorithms.graph.CycleDetection;
-import com.jwetherell.algorithms.graph.Dijkstra;
-import com.jwetherell.algorithms.graph.FloydWarshall;
-import com.jwetherell.algorithms.graph.Johnson;
-import com.jwetherell.algorithms.graph.Prim;
-import com.jwetherell.algorithms.graph.TopologicalSort;
-
-@SuppressWarnings("unchecked")
-public class DataStructures {
-
- private static final int NUMBER_OF_TESTS = 3;
- private static final Random RANDOM = new Random();
- private static final int ARRAY_SIZE = 1000;
- private static final int RANDOM_SIZE = 1000 * ARRAY_SIZE;
- private static final Integer INVALID = RANDOM_SIZE + 10;
- private static final DecimalFormat FORMAT = new DecimalFormat("0.##");
-
- private static Integer[] unsorted = null;
- private static Integer[] sorted = null;
- private static String string = null;
-
- private static int debug = 1; // Debug level. 0=None, 1=Time and Memory (if enabled), 2=Time, Memory, data structure debug
- private static boolean debugTime = true; // How much time to: add all, remove all, add all items in reverse order, remove all
- private static boolean debugMemory = true; // How much memory is used by the data structure
- private static boolean validateStructure = true; // Is the data structure valid (passed invariants) and proper size
- private static boolean validateContents = true; // Was the item added/removed really added/removed from the structure
- private static boolean validateIterator = true; // Does the iterator(s) work
-
- private static final int TESTS = 38; // Max number of dynamic data structures to test
- private static final String[] testNames = new String[TESTS]; // Array to hold the test names
- private static final long[][] testResults = new long[TESTS][]; // Array to hold the test results
- private static int testIndex = 0; // Index into the tests
- private static int testNumber = 0; // Number of aggregate tests which have been run
-
- private static enum Type {Integer, String};
-
- public static void main(String[] args) {
- System.out.println("Starting tests.");
- boolean passed = false;
- for (int i = 0; i < NUMBER_OF_TESTS; i++) {
- try {
- passed = runTests();
- } catch (NullPointerException e) {
- System.err.println(string);
- throw e;
- }
- if (!passed) break;
- }
- if (passed) System.out.println("Tests finished. All passed.");
- else System.err.println("Tests finished. Detected a failure.");
- }
-
- private static void generateData() {
- System.out.println("Generating data.");
- StringBuilder builder = new StringBuilder();
- builder.append("Array=");
- unsorted = new Integer[ARRAY_SIZE];
- java.util.Set set = new java.util.HashSet();
- for (int i = 0; i < ARRAY_SIZE; i++) {
- Integer j = RANDOM.nextInt(RANDOM_SIZE);
- // Make sure there are no duplicates
- boolean found = true;
- while (found) {
- if (set.contains(j)) {
- j = RANDOM.nextInt(RANDOM_SIZE);
- } else {
- unsorted[i] = j;
- set.add(j);
- found = false;
- }
- }
- unsorted[i] = j;
- if (i!=ARRAY_SIZE-1) builder.append(j).append(',');
- }
- set.clear();
- set = null;
- builder.append('\n');
- string = builder.toString();
- if (debug > 1) System.out.println(string);
-
- sorted = Arrays.copyOf(unsorted, unsorted.length);
- Arrays.sort(sorted);
-
- System.out.println("Generated data.");
- }
-
- private static boolean runTests() {
- testIndex = 0;
- testNumber++;
-
- generateData();
-
- boolean passed = true;
-
- // Trees
-
- passed = testJavaRedBlackIntegerTree();
- if (!passed) {
- System.err.println("Java Red-Black [Integer] failed.");
- return false;
- }
-
- passed = testRedBlackTree();
- if (!passed) {
- System.err.println("Red-Black Tree failed.");
- return false;
- }
-
- passed = testAVLTree();
- if (!passed) {
- System.err.println("AVL Tree failed.");
- return false;
- }
-
- passed = testSplayTree();
- if (!passed) {
- System.err.println("Splay Tree failed.");
- return false;
- }
-
- passed = testBTree();
- if (!passed) {
- System.err.println("B-Tree failed.");
- return false;
- }
-
- passed = testTreap();
- if (!passed) {
- System.err.println("Treap failed.");
- return false;
- }
-
- passed = testBST();
- if (!passed) {
- System.err.println("BST failed.");
- return false;
- }
-
- passed = testJavaRedBlackStringTree();
- if (!passed) {
- System.err.println("Java Red-Black [String] failed.");
- return false;
- }
-
- passed = testTrie();
- if (!passed) {
- System.err.println("Trie failed.");
- return false;
- }
-
- passed = testPatriciaTrie();
- if (!passed) {
- System.err.println("Patricia Trie failed.");
- return false;
- }
-
- // Sets
-
- passed = testJavaSkipList();
- if (!passed) {
- System.err.println("Java's Skip List failed.");
- return false;
- }
-
- passed = testSkipList();
- if (!passed) {
- System.err.println("Skip List failed.");
- return false;
- }
-
- // Heaps
-
- passed = testJavaMinHeap();
- if (!passed) {
- System.err.println("Java Min-Heap failed.");
- return false;
- }
-
- passed = testMinHeap();
- if (!passed) {
- System.err.println("Min-Heap failed.");
- return false;
- }
-
- passed = testJavaMaxHeap();
- if (!passed) {
- System.err.println("Java Max-Heap failed.");
- return false;
- }
-
- passed = testMaxHeap();
- if (!passed) {
- System.err.println("Max-Heap failed.");
- return false;
- }
-
- // Lists
-
- passed = testJavaArrayList();
- if (!passed) {
- System.err.println("Java List failed.");
- return false;
- }
-
- passed = testArrayList();
- if (!passed) {
- System.err.println("List failed.");
- return false;
- }
-
- passed = testJavaLinkedList();
- if (!passed) {
- System.err.println("Java List failed.");
- return false;
- }
-
- passed = testLinkedList();
- if (!passed) {
- System.err.println("List failed.");
- return false;
- }
-
- // Queues
-
- passed = testJavaArrayQueue();
- if (!passed) {
- System.err.println("Java Queue failed.");
- return false;
- }
-
- passed = testArrayQueue();
- if (!passed) {
- System.err.println("Queue failed.");
- return false;
- }
-
- passed = testJavaLinkedQueue();
- if (!passed) {
- System.err.println("Java Queue failed.");
- return false;
- }
-
- passed = testLinkedQueue();
- if (!passed) {
- System.err.println("Queue failed.");
- return false;
- }
-
- // Stacks
-
- passed = testJavaStack();
- if (!passed) {
- System.err.println("Java Stack failed.");
- return false;
- }
-
- passed = testArrayStack();
- if (!passed) {
- System.err.println("Stack failed.");
- return false;
- }
-
- passed = testLinkedStack();
- if (!passed) {
- System.err.println("Stack failed.");
- return false;
- }
-
- // Maps
-
- passed = testJavaHashMap();
- if (!passed) {
- System.err.println("Java Hash Map failed.");
- return false;
- }
-
- passed = testHashMap();
- if (!passed) {
- System.err.println("Hash Map failed.");
- return false;
- }
-
- passed = testJavaTreeMap();
- if (!passed) {
- System.err.println("Java Tree Map failed.");
- return false;
- }
-
- passed = testTreeMap();
- if (!passed) {
- System.err.println("Tree Map failed.");
- return false;
- }
-
- passed = testTrieMap();
- if (!passed) {
- System.err.println("Trie Map failed.");
- return false;
- }
-
- passed = testRadixTrie();
- if (!passed) {
- System.err.println("Radix Trie failed.");
- return false;
- }
-
- passed = testJavaSkipListMap();
- if (!passed) {
- System.err.println("Java's Skip List Map failed.");
- return false;
- }
-
- passed = testSkipListMap();
- if (!passed) {
- System.err.println("Skip List Map failed.");
- return false;
- }
-
- passed = testHAMT();
- if (!passed) {
- System.err.println("HAMT failed.");
- return false;
- }
-
- if (debugTime && debugMemory) {
- String results = getTestResults(testNumber, testNames, testResults);
- System.out.println(results);
- }
-
- // MY STATIC DATA STRUCTURES
-
- passed = testCompactSuffixTrie();
- if (!passed) {
- System.err.println("Compact Suffix Trie failed.");
- return false;
- }
-
- passed = testGraph();
- if (!passed) {
- System.err.println("Graph failed.");
- return false;
- }
-
- passed = testIntervalTree();
- if (!passed) {
- System.err.println("Interval Tree failed.");
- return false;
- }
-
- passed = testKdTree();
- if (!passed) {
- System.err.println("k-d Tree Tree failed.");
- return false;
- }
-
- passed = testMatrix();
- if (!passed) {
- System.err.println("Matrix failed.");
- return false;
- }
-
- passed = testQuadTree();
- if (!passed) {
- System.err.println("QuadTree failed.");
- return false;
- }
-
- passed = testSegmentTree();
- if (!passed) {
- System.err.println("Segment Tree failed.");
- return false;
- }
-
- passed = testSuffixTree();
- if (!passed) {
- System.err.println("Suffix Tree failed.");
- return false;
- }
-
- passed = testSuffixTrie();
- if (!passed) {
- System.err.println("Suffix Trie failed.");
- return false;
- }
-
- return true;
- }
-
- private static void handleError(Object obj) {
- System.err.println(string);
- System.err.println(obj.toString());
- throw new RuntimeException();
- }
-
- private static boolean testAVLTree() {
- String bstName = "AVL Tree";
- BinarySearchTree bst = new AVLTree();
- Collection bstCollection = bst.toCollection();
-
- if((validateStructure||validateContents) && !testTree(bst,Type.Integer,bstName)) return false;
- if(!testJavaCollection(bstCollection,Type.Integer,bstName)) return false;
- return true;
- }
-
- private static boolean testBTree() {
- String bstName = "B-Tree";
- BTree bst = new BTree(2);
- Collection bstCollection = bst.toCollection();
-
- if((validateStructure||validateContents) && !testTree(bst,Type.Integer,bstName)) return false;
- if(!testJavaCollection(bstCollection,Type.Integer,bstName)) return false;
- return true;
- }
-
- private static boolean testBST() {
- String bstName = "BST";
- BinarySearchTree bst = new BinarySearchTree();
- Collection bstCollection = bst.toCollection();
-
- if((validateStructure||validateContents) && !testTree(bst,Type.Integer,bstName)) return false;
- if(!testJavaCollection(bstCollection,Type.Integer,bstName)) return false;
- return true;
- }
-
- private static boolean testCompactSuffixTrie() {
- if (debug > 1) System.out.println("Compact Suffix Trie.");
- String bookkeeper = "bookkeeper";
- CompactSuffixTrie trie = new CompactSuffixTrie(bookkeeper);
- if (debug > 1) System.out.println(trie.toString());
- if (debug > 1) System.out.println(trie.getSuffixes());
-
- boolean exists = trie.doesSubStringExist(bookkeeper);
- if (!exists) {
- System.err.println("YIKES!! " + bookkeeper + " doesn't exists.");
- handleError(trie);
- return false;
- }
-
- String failed = "booker";
- exists = trie.doesSubStringExist(failed);
- if (exists) {
- System.err.println("YIKES!! " + failed + " exists.");
- handleError(trie);
- return false;
- }
-
- String pass = "kkee";
- exists = trie.doesSubStringExist(pass);
- if (!exists) {
- System.err.println("YIKES!! " + pass + " doesn't exists.");
- handleError(trie);
- return false;
- }
-
- if (debug > 1) System.out.println();
-
- return true;
- }
-
- private static boolean testGraph() {
- { // UNDIRECTED GRAPH
- if (debug > 1) System.out.println("Undirected Graph.");
- java.util.List> verticies = new ArrayList>();
- Graph.Vertex v1 = new Graph.Vertex(1);
- verticies.add(v1);
- Graph.Vertex v2 = new Graph.Vertex(2);
- verticies.add(v2);
- Graph.Vertex v3 = new Graph.Vertex(3);
- verticies.add(v3);
- Graph.Vertex v4 = new Graph.Vertex(4);
- verticies.add(v4);
- Graph.Vertex v5 = new Graph.Vertex(5);
- verticies.add(v5);
- Graph.Vertex v6 = new Graph.Vertex(6);
- verticies.add(v6);
-
- java.util.List> edges = new ArrayList>();
- Graph.Edge e1_2 = new Graph.Edge(7, v1, v2);
- edges.add(e1_2);
- Graph.Edge e1_3 = new Graph.Edge(9, v1, v3);
- edges.add(e1_3);
- Graph.Edge e1_6 = new Graph.Edge(14, v1, v6);
- edges.add(e1_6);
- Graph.Edge e2_3 = new Graph.Edge(10, v2, v3);
- edges.add(e2_3);
- Graph.Edge e2_4 = new Graph.Edge(15, v2, v4);
- edges.add(e2_4);
- Graph.Edge e3_4 = new Graph.Edge(11, v3, v4);
- edges.add(e3_4);
- Graph.Edge e3_6 = new Graph.Edge(2, v3, v6);
- edges.add(e3_6);
- Graph.Edge e5_6 = new Graph.Edge(9, v5, v6);
- edges.add(e5_6);
- Graph.Edge e4_5 = new Graph.Edge(6, v4, v5);
- edges.add(e4_5);
-
- Graph undirected = new Graph(verticies, edges);
- if (debug > 1) System.out.println(undirected.toString());
-
- Graph.Vertex start = v1;
- if (debug > 1) System.out.println("Dijstra's shortest paths of the undirected graph from " + start.getValue());
- Map, Graph.CostPathPair> map1 = Dijkstra.getShortestPaths(undirected, start);
- if (debug > 1) System.out.println(getPathMapString(start, map1));
-
- Graph.Vertex end = v5;
- if (debug > 1) System.out.println("Dijstra's shortest path of the undirected graph from " + start.getValue() + " to " + end.getValue());
- Graph.CostPathPair pair1 = Dijkstra.getShortestPath(undirected, start, end);
- if (debug > 1) {
- if (pair1 != null) System.out.println(pair1.toString());
- else System.out.println("No path from " + start.getValue() + " to " + end.getValue());
- }
-
- start = v1;
- if (debug > 1) System.out.println("Bellman-Ford's shortest paths of the undirected graph from " + start.getValue());
- Map, Graph.CostPathPair> map2 = BellmanFord.getShortestPaths(undirected, start);
- if (debug > 1) System.out.println(getPathMapString(start, map2));
-
- end = v5;
- if (debug > 1) System.out.println("Bellman-Ford's shortest path of the undirected graph from " + start.getValue() + " to " + end.getValue());
- Graph.CostPathPair pair2 = BellmanFord.getShortestPath(undirected, start, end);
- if (debug > 1) {
- if (pair2 != null) System.out.println(pair2.toString());
- else System.out.println("No path from " + start.getValue() + " to " + end.getValue());
- }
-
- // MST
-
- if (debug > 1) System.out.println("Prim's minimum spanning tree of the undirected graph from " + start.getValue());
- Graph.CostPathPair pair = Prim.getMinimumSpanningTree(undirected, start);
- if (debug > 1) System.out.println(pair.toString());
-
- // Prim on a graph with cycles
- java.util.List> cyclicVerticies = new ArrayList>();
- Graph.Vertex cv1 = new Graph.Vertex(1);
- cyclicVerticies.add(cv1);
- Graph.Vertex cv2 = new Graph.Vertex(2);
- cyclicVerticies.add(cv2);
- Graph.Vertex cv3 = new Graph.Vertex(3);
- cyclicVerticies.add(cv3);
- Graph.Vertex cv4 = new Graph.Vertex(4);
- cyclicVerticies.add(cv4);
- Graph.Vertex cv5 = new Graph.Vertex(5);
- cyclicVerticies.add(cv5);
-
- java.util.List> cyclicEdges = new ArrayList>();
- Graph.Edge ce1_2 = new Graph.Edge(3, cv1, cv2);
- cyclicEdges.add(ce1_2);
- Graph.Edge ce2_3 = new Graph.Edge(2, cv2, cv3);
- cyclicEdges.add(ce2_3);
- Graph.Edge ce3_4 = new Graph.Edge(4, cv3, cv4);
- cyclicEdges.add(ce3_4);
- Graph.Edge ce4_1 = new Graph.Edge(1, cv4, cv1);
- cyclicEdges.add(ce4_1);
- Graph.Edge ce4_5 = new Graph.Edge(1, cv4, cv5);
- cyclicEdges.add(ce4_5);
-
- Graph cyclicUndirected = new Graph(cyclicVerticies, cyclicEdges);
- if (debug > 1) System.out.println(cyclicUndirected.toString());
-
- start = cv1;
- if (debug > 1) System.out.println("Prim's minimum spanning tree of a cyclic undirected graph from " + start.getValue());
- Graph.CostPathPair cyclicPair = Prim.getMinimumSpanningTree(cyclicUndirected, start);
- if (debug > 1) System.out.println(cyclicPair.toString());
-
- if (debug > 1) System.out.println();
- }
-
- { // DIRECTED GRAPH
- if (debug > 1) System.out.println("Directed Graph.");
- java.util.List> verticies = new ArrayList>();
- Graph.Vertex v1 = new Graph.Vertex(1);
- verticies.add(v1);
- Graph.Vertex v2 = new Graph.Vertex(2);
- verticies.add(v2);
- Graph.Vertex v3 = new Graph.Vertex(3);
- verticies.add(v3);
- Graph.Vertex v4 = new Graph.Vertex(4);
- verticies.add(v4);
- Graph.Vertex v5 = new Graph.Vertex(5);
- verticies.add(v5);
- Graph.Vertex v6 = new Graph.Vertex(6);
- verticies.add(v6);
- Graph.Vertex v7 = new Graph.Vertex(7);
- verticies.add(v7);
-
- java.util.List> edges = new ArrayList>();
- Graph.Edge e1_2 = new Graph.Edge(7, v1, v2);
- edges.add(e1_2);
- Graph.Edge e1_3 = new Graph.Edge(9, v1, v3);
- edges.add(e1_3);
- Graph.Edge e1_6 = new Graph.Edge(14, v1, v6);
- edges.add(e1_6);
- Graph.Edge e2_3 = new Graph.Edge(10, v2, v3);
- edges.add(e2_3);
- Graph.Edge e2_4 = new Graph.Edge(15, v2, v4);
- edges.add(e2_4);
- Graph.Edge e3_4 = new Graph.Edge(11, v3, v4);
- edges.add(e3_4);
- Graph.Edge e3_6 = new Graph.Edge(2, v3, v6);
- edges.add(e3_6);
- Graph.Edge e6_5 = new Graph.Edge(9, v6, v5);
- edges.add(e6_5);
- Graph.Edge e4_5 = new Graph.Edge(6, v4, v5);
- edges.add(e4_5);
- Graph.Edge e4_7 = new Graph.Edge(16, v4, v7);
- edges.add(e4_7);
-
- Graph directed = new Graph(Graph.TYPE.DIRECTED, verticies, edges);
- if (debug > 1) System.out.println(directed.toString());
-
- Graph.Vertex start = v1;
- if (debug > 1) System.out.println("Dijstra's shortest paths of the directed graph from " + start.getValue());
- Map, Graph.CostPathPair> map = Dijkstra.getShortestPaths(directed, start);
- if (debug > 1) System.out.println(getPathMapString(start, map));
-
- Graph.Vertex end = v5;
- if (debug > 1) System.out.println("Dijstra's shortest path of the directed graph from " + start.getValue() + " to " + end.getValue());
- Graph.CostPathPair pair = Dijkstra.getShortestPath(directed, start, end);
- if (debug > 1) {
- if (pair != null) System.out.println(pair.toString());
- else System.out.println("No path from " + start.getValue() + " to " + end.getValue());
- }
-
- start = v1;
- if (debug > 1) System.out.println("Bellman-Ford's shortest paths of the undirected graph from " + start.getValue());
- Map, Graph.CostPathPair> map2 = BellmanFord.getShortestPaths(directed, start);
- if (debug > 1) System.out.println(getPathMapString(start, map2));
-
- end = v5;
- if (debug > 1) System.out.println("Bellman-Ford's shortest path of the undirected graph from " + start.getValue() + " to " + end.getValue());
- Graph.CostPathPair pair2 = BellmanFord.getShortestPath(directed, start, end);
- if (debug > 1) {
- if (pair2 != null) System.out.println(pair2.toString());
- else System.out.println("No path from " + start.getValue() + " to " + end.getValue());
- }
-
- if (debug > 1) System.out.println();
- }
-
- { // DIRECTED GRAPH (WITH NEGATIVE WEIGHTS)
- if (debug > 1) System.out.println("Undirected Graph with Negative Weights.");
- java.util.List> verticies = new ArrayList>();
- Graph.Vertex v1 = new Graph.Vertex(1);
- verticies.add(v1);
- Graph.Vertex v2 = new Graph.Vertex(2);
- verticies.add(v2);
- Graph.Vertex v3 = new Graph.Vertex(3);
- verticies.add(v3);
- Graph.Vertex v4 = new Graph.Vertex(4);
- verticies.add(v4);
-
- java.util.List> edges = new ArrayList>();
- Graph.Edge e1_4 = new Graph.Edge(2, v1, v4);
- edges.add(e1_4);
- Graph.Edge e2_1 = new Graph.Edge(6, v2, v1);
- edges.add(e2_1);
- Graph.Edge e2_3 = new Graph.Edge(3, v2, v3);
- edges.add(e2_3);
- Graph.Edge e3_1 = new Graph.Edge(4, v3, v1);
- edges.add(e3_1);
- Graph.Edge e3_4 = new Graph.Edge(5, v3, v4);
- edges.add(e3_4);
- Graph.Edge e4_2 = new Graph.Edge(-7, v4, v2);
- edges.add(e4_2);
- Graph.Edge e4_3 = new Graph.Edge(-3, v4, v3);
- edges.add(e4_3);
-
- Graph directed = new Graph(Graph.TYPE.DIRECTED, verticies, edges);
- if (debug > 1) System.out.println(directed.toString());
-
- Graph.Vertex start = v1;
- if (debug > 1) System.out.println("Bellman-Ford's shortest paths of the directed graph from " + start.getValue());
- Map, Graph.CostPathPair> map2 = BellmanFord.getShortestPaths(directed, start);
- if (debug > 1) System.out.println(getPathMapString(start, map2));
-
- Graph.Vertex end = v3;
- if (debug > 1) System.out.println("Bellman-Ford's shortest path of the directed graph from " + start.getValue() + " to " + end.getValue());
- Graph.CostPathPair pair2 = BellmanFord.getShortestPath(directed, start, end);
- if (debug > 1) {
- if (pair2 != null) System.out.println(pair2.toString());
- else System.out.println("No path from " + start.getValue() + " to " + end.getValue());
- }
-
- if (debug > 1) System.out.println("Johnson's all-pairs shortest path of the directed graph.");
- Map, Map, Set>>> paths = Johnson.getAllPairsShortestPaths(directed);
- if (debug > 1) {
- if (paths == null) System.out.println("Directed graph contains a negative weight cycle.");
- else System.out.println(getPathMapString(paths));
- }
-
- if (debug > 1) System.out.println("Floyd-Warshall's all-pairs shortest path weights of the directed graph.");
- Map, Map, Integer>> pathWeights = FloydWarshall.getAllPairsShortestPaths(directed);
- if (debug > 1) System.out.println(getWeightMapString(pathWeights));
-
- if (debug > 1) System.out.println();
- }
-
- { // UNDIRECTED GRAPH
- if (debug > 1) System.out.println("Undirected Graph cycle check.");
- java.util.List> cycledVerticies = new ArrayList>();
- Graph.Vertex cv1 = new Graph.Vertex(1);
- cycledVerticies.add(cv1);
- Graph.Vertex cv2 = new Graph.Vertex(2);
- cycledVerticies.add(cv2);
- Graph.Vertex cv3 = new Graph.Vertex(3);
- cycledVerticies.add(cv3);
- Graph.Vertex cv4 = new Graph.Vertex(4);
- cycledVerticies.add(cv4);
- Graph.Vertex cv5 = new Graph.Vertex(5);
- cycledVerticies.add(cv5);
- Graph.Vertex cv6 = new Graph.Vertex(6);
- cycledVerticies.add(cv6);
-
- java.util.List> cycledEdges = new ArrayList>();
- Graph.Edge ce1_2 = new Graph.Edge(7, cv1, cv2);
- cycledEdges.add(ce1_2);
- Graph.Edge ce2_4 = new Graph.Edge(15, cv2, cv4);
- cycledEdges.add(ce2_4);
- Graph.Edge ce3_4 = new Graph.Edge(11, cv3, cv4);
- cycledEdges.add(ce3_4);
- Graph.Edge ce3_6 = new Graph.Edge(2, cv3, cv6);
- cycledEdges.add(ce3_6);
- Graph.Edge ce5_6 = new Graph.Edge(9, cv5, cv6);
- cycledEdges.add(ce5_6);
- Graph.Edge ce4_5 = new Graph.Edge(6, cv4, cv5);
- cycledEdges.add(ce4_5);
-
- Graph undirectedWithCycle = new Graph(cycledVerticies, cycledEdges);
- if (debug > 1) System.out.println(undirectedWithCycle.toString());
-
- if (debug > 1) {
- System.out.println("Cycle detection of the undirected graph.");
- boolean result = CycleDetection.detect(undirectedWithCycle);
- System.out.println("result=" + result);
- System.out.println();
- }
-
- java.util.List> verticies = new ArrayList>();
- Graph.Vertex v1 = new Graph.Vertex(1);
- verticies.add(v1);
- Graph.Vertex v2 = new Graph.Vertex(2);
- verticies.add(v2);
- Graph.Vertex v3 = new Graph.Vertex(3);
- verticies.add(v3);
- Graph.Vertex v4 = new Graph.Vertex(4);
- verticies.add(v4);
- Graph.Vertex v5 = new Graph.Vertex(5);
- verticies.add(v5);
- Graph.Vertex v6 = new Graph.Vertex(6);
- verticies.add(v6);
-
- java.util.List> edges = new ArrayList>();
- Graph.Edge e1_2 = new Graph.Edge(7, v1, v2);
- edges.add(e1_2);
- Graph.Edge e2_4 = new Graph.Edge(15, v2, v4);
- edges.add(e2_4);
- Graph.Edge e3_4 = new Graph.Edge(11, v3, v4);
- edges.add(e3_4);
- Graph.Edge e3_6 = new Graph.Edge(2, v3, v6);
- edges.add(e3_6);
- Graph.Edge e4_5 = new Graph.Edge(6, v4, v5);
- edges.add(e4_5);
-
- Graph undirectedWithoutCycle = new Graph(verticies, edges);
- if (debug > 1) System.out.println(undirectedWithoutCycle.toString());
-
- if (debug > 1) {
- System.out.println("Cycle detection of the undirected graph.");
- boolean result = CycleDetection.detect(undirectedWithoutCycle);
- System.out.println("result=" + result);
- System.out.println();
- }
- }
-
- { // DIRECTED GRAPH
- if (debug > 1) System.out.println("Directed Graph topological sort.");
- java.util.List> verticies = new ArrayList>();
- Graph.Vertex cv1 = new Graph.Vertex(1);
- verticies.add(cv1);
- Graph.Vertex cv2 = new Graph.Vertex(2);
- verticies.add(cv2);
- Graph.Vertex cv3 = new Graph.Vertex(3);
- verticies.add(cv3);
- Graph.Vertex cv4 = new Graph.Vertex(4);
- verticies.add(cv4);
- Graph.Vertex cv5 = new Graph.Vertex(5);
- verticies.add(cv5);
- Graph.Vertex cv6 = new Graph.Vertex(6);
- verticies.add(cv6);
-
- java.util.List> edges = new ArrayList>();
- Graph.Edge ce1_2 = new Graph.Edge(1, cv1, cv2);
- edges.add(ce1_2);
- Graph.Edge ce2_4 = new Graph.Edge(2, cv2, cv4);
- edges.add(ce2_4);
- Graph.Edge ce4_3 = new Graph.Edge(3, cv4, cv3);
- edges.add(ce4_3);
- Graph.Edge ce3_6 = new Graph.Edge(4, cv3, cv6);
- edges.add(ce3_6);
- Graph.Edge ce5_6 = new Graph.Edge