diff --git a/.classpath b/.classpath
deleted file mode 100644
index 18d70f02..00000000
--- a/.classpath
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..2e6c8bb4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+# Created by .ignore support plugin (hsz.mobi)
+### Example user template template
+### Example user template
+
+# IntelliJ project files
+.idea
+*.iml
+out
+gen
+.html
+bin/LICENSE
+bin/README.md
+bin/com/jwetherell/
+bin/lib/
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..5c98b428
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,2 @@
+# Default ignored files
+/workspace.xml
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 00000000..9db94d5f
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+JavaAlgorithmsImplementation
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..6560a989
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..84da703c
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..6257a3e4
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..35eb1ddf
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.project b/.project
deleted file mode 100644
index 3cd55b5c..00000000
--- a/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- JavaAlgorithmsImplementation
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
-
-
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 21101703..00000000
--- a/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,12 +0,0 @@
-#Thu Dec 15 14:40:25 EST 2011
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/JavaAlgorithmsImplementation.iml b/JavaAlgorithmsImplementation.iml
new file mode 100644
index 00000000..77779b49
--- /dev/null
+++ b/JavaAlgorithmsImplementation.iml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 49b9be2c..ecc6437b 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,148 @@ java-algorithms-implementation
==============================
Algorithms and Data Structures implemented in Java
+
+
+This is a collection of algorithms and data structures which I've implement over the years in my academic and professional life. The code isn't overly-optimized but is written to be correct and readable. The algorithms and data structures are well tested and, unless noted, are believe to be 100% correct.
+
+* Created by Justin Wetherell
+* 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
+
+# What's been implemented:
+
+## Data Structures
+* AVL Tree
+* B-Tree
+* Binary Heap [backed by an array or a tree]
+* Binary Search Tree
+* Compact Suffix Trie [backed by a Patricia Trie]
+* Graph
+ + Undirected
+ + Directed (Digraph)
+* Hash Array Mapped Trie (HAMT)
+* Hash Map (associative array)
+* Interval Tree
+* KD Tree (k-dimensional tree or k-d tree)
+* List [backed by an array or a linked list]
+* Matrix
+* Patricia Trie
+* Quad-Tree (Point-Region or MX-CIF)
+* Queue [backed by an array or a linked list]
+* Radix Trie (associative array) [backed by a Patricia Trie]
+* Red-Black Tree
+* Segment Tree
+* Skip List
+* Splay Tree
+* Stack [backed by an array or a linked list]
+* Suffix Tree (Ukkonen's algorithm)
+* Suffix Trie [backed by a Trie]
+* Treap
+* Tree Map (associative array) [backed by an AVL Tree]
+* Trie
+* Trie Map (associative array) [backed by a Trie]
+
+## Mathematics
+* Distance
+ + chebyshev
+ + euclidean
+* Division
+ + using a loop
+ + using recursion
+ + using shifts and multiplication
+ + using only shifts
+ + using logarithm
+* Multiplication
+ + using a loop
+ + using recursion
+ + using only shifts
+ + using logarithms
+* Primes
+ + is prime
+ + prime factorization
+ + sieve of eratosthenes
+
+## Numbers
+* Integers
+ + 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
+ + greatest common divisor
+ - using Euclid's algorithm
+ + to English (e.g. 1 would return "one")
+* Longs
+ + to binary String
+ - using divide and modulus
+ - using right shift and modulus
+ - using BigDecimal
+
+## Path
+* Find shortest path(s) in a Graph from a starting Vertex
+ - Dijkstra's algorithm (non-negative weight graphs)
+ - Bellman-Ford algorithm (negative and positive weight graphs)
+* Find minimum spanning tree
+ - Prim's (undirected graphs)
+* Find all pairs shortest path
+ - Johnsons's algorithm (negative and positive weight graphs)
+ - Floyd-Warshall (negative and positive weight graphs)
+* Cycle detection
+ - Depth first search while keeping track of visited Verticies
+* Topological sort
+
+## Search
+* Get index of value in array
+ + Linear
+ + Quickselect
+ + Binary [sorted array input only]
+ + Optimized binary (binary until a threashold then linear) [sorted array input only]
+ + Interpolation [sorted array input only]
+
+## Sequences
+* Find longest common subsequence (dynamic programming)
+* Find number of times a subsequence occurs in a sequence (dynamic programming)
+* Find i-th element in a Fibonacci sequence
+ + using a loop
+ + using recursion
+ + using matrix multiplication
+ + using Binet's formula
+* Find total of all elements in a sequence
+ + using a loop
+ + using Triangular numbers
+
+## Sorts
+* American Flag Sort
+* Bubble Sort
+* Counting Sort (Integers only)
+* Heap Sort
+* Insertion Sort
+* Merge Sort
+* Quick Sort
+* Radix Sort (Integers only)
+* Shell's Sort
+
+## String Functions
+* 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
+
diff --git a/Test Results - Sorts_testInsertionSorts.html b/Test Results - Sorts_testInsertionSorts.html
new file mode 100644
index 00000000..3f6d761a
--- /dev/null
+++ b/Test Results - Sorts_testInsertionSorts.html
@@ -0,0 +1,614 @@
+
+
+
+
+ Test Results — Sorts.testInsertionSorts
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "C:\Program Files\Java\jdk\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:D:\program\intelliJ\lib\idea_rt.jar=58805:D:\program\intelliJ\bin -Dfile.encoding=UTF-8 -classpath "D:\program\intelliJ\lib\idea_rt.jar;D:\program\intelliJ\plugins\junit\lib\junit-rt.jar;D:\program\intelliJ\plugins\junit\lib\junit5-rt.jar;D:\program\ideaworkspace\java-algo\bin;C:\Program Files\Java\jdk\jre\lib\charsets.jar;C:\Program Files\Java\jdk\jre\lib\deploy.jar;C:\Program Files\Java\jdk\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk\jre\lib\javaws.jar;C:\Program Files\Java\jdk\jre\lib\jce.jar;C:\Program Files\Java\jdk\jre\lib\jfr.jar;C:\Program Files\Java\jdk\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk\jre\lib\jsse.jar;C:\Program Files\Java\jdk\jre\lib\management-agent.jar;C:\Program Files\Java\jdk\jre\lib\plugin.jar;C:\Program Files\Java\jdk\jre\lib\resources.jar;C:\Program Files\Java\jdk\jre\lib\rt.jar;D:\program\intelliJ\lib\hamcrest-core-1.3.jar;D:\program\ideaworkspace\java-algo\lib\junit-jupiter-5.4.2.jar;D:\program\ideaworkspace\java-algo\lib\junit-jupiter-api-5.4.2.jar;D:\program\ideaworkspace\java-algo\lib\apiguardian-api-1.0.0.jar;D:\program\ideaworkspace\java-algo\lib\opentest4j-1.1.1.jar;D:\program\ideaworkspace\java-algo\lib\junit-platform-commons-1.4.2.jar;D:\program\ideaworkspace\java-algo\lib\junit-jupiter-params-5.4.2.jar;D:\program\ideaworkspace\java-algo\lib\junit-jupiter-engine-5.4.2.jar;D:\program\ideaworkspace\java-algo\lib\junit-platform-engine-1.4.2.jar;D:\program\ideaworkspace\java-algo\lib\junit-4.11.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.jwetherell.algorithms.sorts.test.Sorts,testInsertionSorts
+Process finished with exit code 0
+
+
+
+ 201 ms
+ passed Sorts.testInsertionSorts
+
+
+
+
+
+
+
+
diff --git a/bin/com/gw/myalgo/HelloAlgo.class b/bin/com/gw/myalgo/HelloAlgo.class
new file mode 100644
index 00000000..9e65f28d
Binary files /dev/null and b/bin/com/gw/myalgo/HelloAlgo.class differ
diff --git a/lib/apiguardian-api-1.0.0.jar b/lib/apiguardian-api-1.0.0.jar
new file mode 100644
index 00000000..6cbff70f
Binary files /dev/null and b/lib/apiguardian-api-1.0.0.jar differ
diff --git a/lib/commons-lang3-3.9.jar b/lib/commons-lang3-3.9.jar
new file mode 100644
index 00000000..0d896939
Binary files /dev/null and b/lib/commons-lang3-3.9.jar differ
diff --git a/lib/junit-4.11.jar b/lib/junit-4.11.jar
new file mode 100644
index 00000000..aaf74448
Binary files /dev/null and b/lib/junit-4.11.jar differ
diff --git a/lib/junit-jupiter-5.4.2.jar b/lib/junit-jupiter-5.4.2.jar
new file mode 100644
index 00000000..b3bf6976
Binary files /dev/null and b/lib/junit-jupiter-5.4.2.jar differ
diff --git a/lib/junit-jupiter-api-5.4.2.jar b/lib/junit-jupiter-api-5.4.2.jar
new file mode 100644
index 00000000..40828b7a
Binary files /dev/null and b/lib/junit-jupiter-api-5.4.2.jar differ
diff --git a/lib/junit-jupiter-engine-5.4.2.jar b/lib/junit-jupiter-engine-5.4.2.jar
new file mode 100644
index 00000000..3444a980
Binary files /dev/null and b/lib/junit-jupiter-engine-5.4.2.jar differ
diff --git a/lib/junit-jupiter-params-5.4.2.jar b/lib/junit-jupiter-params-5.4.2.jar
new file mode 100644
index 00000000..ee565041
Binary files /dev/null and b/lib/junit-jupiter-params-5.4.2.jar differ
diff --git a/lib/junit-platform-commons-1.4.2.jar b/lib/junit-platform-commons-1.4.2.jar
new file mode 100644
index 00000000..27055251
Binary files /dev/null and b/lib/junit-platform-commons-1.4.2.jar differ
diff --git a/lib/junit-platform-engine-1.4.2.jar b/lib/junit-platform-engine-1.4.2.jar
new file mode 100644
index 00000000..2c46ae92
Binary files /dev/null and b/lib/junit-platform-engine-1.4.2.jar differ
diff --git a/lib/opentest4j-1.1.1.jar b/lib/opentest4j-1.1.1.jar
new file mode 100644
index 00000000..3f355292
Binary files /dev/null and b/lib/opentest4j-1.1.1.jar differ
diff --git a/src/com/gw/myalgo/HelloAlgo.java b/src/com/gw/myalgo/HelloAlgo.java
new file mode 100644
index 00000000..ea2a9aa4
--- /dev/null
+++ b/src/com/gw/myalgo/HelloAlgo.java
@@ -0,0 +1,7 @@
+package com.gw.myalgo;
+
+public class HelloAlgo {
+ public static void main(String[] args) {
+ System.out.println("Hello, idea algo");
+ }
+}
diff --git a/src/com/gw/myalgo/datastructure/SingleLinkedList.java b/src/com/gw/myalgo/datastructure/SingleLinkedList.java
new file mode 100644
index 00000000..ca6222ea
--- /dev/null
+++ b/src/com/gw/myalgo/datastructure/SingleLinkedList.java
@@ -0,0 +1,437 @@
+package com.gw.myalgo.datastructure;
+
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * Single Linked list
+ * @author hsden
+ */
+public class SingleLinkedList implements List {
+
+ /**
+ * size of the linked list, the default size is 0
+ */
+ private transient int size = 0;
+
+ /**
+ * head node of the linked list
+ */
+ private Node headNode;
+
+ /**
+ * tail node of the linked list
+ */
+ private Node tailNode;
+
+ public SingleLinkedList(){
+
+ }
+
+ public SingleLinkedList(E firstItem) {
+ Node firstNode = new Node(firstItem,null);
+ this.headNode = firstNode;
+ this.tailNode = firstNode;
+ this.size += 1;
+ }
+
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return false;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return null;
+ }
+
+ @Override
+ public Object[] toArray() {
+ return new Object[0];
+ }
+
+ @Override
+ public T[] toArray(T[] a) {
+ return null;
+ }
+
+ @Override
+ public boolean add(E e) {
+ boolean result = false;
+ if(null == e){
+ return result;
+ } else {
+ Node newNode = new Node(e,null);
+ if(size == 0){
+ this.headNode = newNode;
+ this.tailNode = newNode;
+ } else {
+ this.tailNode.next = newNode;
+ this.tailNode =newNode;
+ }
+
+ this.size += 1;
+ }
+
+
+ return result;
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(Collection> c) {
+ return false;
+ }
+
+ @Override
+ public boolean addAll(Collection extends E> c) {
+ return false;
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends E> c) {
+ return false;
+ }
+
+ @Override
+ public boolean removeAll(Collection> c) {
+ return false;
+ }
+
+ @Override
+ public boolean retainAll(Collection> c) {
+ return false;
+ }
+
+ @Override
+ public void clear() {
+
+ }
+
+ @Override
+ public E get(int index) {
+ return null;
+ }
+
+ @Override
+ public E set(int index, E element) {
+ return null;
+ }
+
+ @Override
+ public void add(int index, E element) {
+
+ }
+
+ @Override
+ public E remove(int index) {
+ return null;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return 0;
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return 0;
+ }
+
+ @Override
+ public ListIterator listIterator() {
+ return null;
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ return null;
+ }
+
+ @Override
+ public List subList(int fromIndex, int toIndex) {
+ return null;
+ }
+
+
+ /**
+ * 正序打印List
+ */
+ public void printList() {
+ if(this.size > 0) {
+ Node tmpNode = this.headNode;
+
+ while(null != tmpNode) {
+ System.out.print(tmpNode.item + " ");
+ tmpNode = tmpNode.next;
+ }
+ System.out.println();
+ }
+ }
+
+ /**
+ * 倒序打印列表, 递归实现
+ */
+ public void printListByRecursion() {
+ if(this.size <= 0) {
+ return;
+ }
+
+ printRecursion(this.headNode);
+ System.out.println();
+ }
+
+ public void printRecursion(Node head) {
+ if(null == head) {
+ return;
+ }
+
+ if(head.next != null) {
+ printRecursion(head.next);
+ }
+
+ System.out.print(head.item + " ");
+
+ }
+
+
+ /**
+ * reverse the list
+ * head->1->2->3->4->6->7,after reverse
+ * head->7->6->5->4->3->2->1
+ */
+ public void simpleReverseList() {
+ if(this.size <= 1) {
+ return;
+ }
+
+ Node newTailNode = headNode, tempHeadNextNode, tempTailNextNode;
+ while(newTailNode.next != null){
+ newTailNode = newTailNode.next;
+ }
+
+ while(headNode != newTailNode) {
+ tempHeadNextNode = headNode.next;
+
+ tempTailNextNode = newTailNode.next;
+ newTailNode.next = headNode;
+ newTailNode.next.next = tempTailNextNode;
+ headNode = tempHeadNextNode;
+ }
+ }
+
+ /**
+ * reverse the list 就地逆序,需要记忆pre
+ * head->1->2->3->4->6->7,after reverse
+ * head->7->6->5->4->3->2->1
+ */
+ public void localReverseList() {
+ if(size <= 1) {
+ return;
+ }
+
+ Node cur = headNode.next, pre = headNode, next;
+ pre.next = null;
+ while(cur!= null) {
+ next = cur.next;
+
+ headNode = cur;
+ cur.next = pre;
+ pre = cur;
+ cur = next;
+ }
+
+ }
+
+ /**
+ * reverse the list by recursion 递归逆序
+ * head->1->2->3->4->6->7,after reverse
+ * head->7->6->5->4->3->2->1
+ */
+ public Node recurseReverse(Node head) {
+ Node newHead;
+ if(null != head && head.next != null) {
+ newHead = recurseReverse(head.next);
+
+ head.next.next = head;
+ head.next = null;
+
+ } else {
+ newHead = head;
+ }
+
+ return newHead;
+ }
+
+
+ public void recurseReverseList() {
+ if(this.size <= 1) {
+ return;
+ }
+
+ headNode =recurseReverse(headNode);
+ }
+
+
+ /**
+ * reverse the list 插入逆序,每次插入最前面
+ * head->1->2->3->4->6->7,after reverse
+ * head->7->6->5->4->3->2->1
+ */
+ public void insertReverseList() {
+ if(this.size <= 1) {
+ return;
+ }
+
+ Node cur = headNode.next, next;
+ headNode.next = null;
+ while(cur != null) {
+ next = cur.next;
+
+ cur.next = headNode;
+ headNode = cur;
+ cur = next;
+ }
+ }
+
+ /**
+ * 给定一个没有排序的链表,去掉其重复项 , 并保留原顺序,
+ * 例如链表 1->3->1->5->5->7,
+ * 去掉重复项后变为 1->3->5->7
+ */
+ public void removeRepeatItemFromUnorderedListM1(){
+ if(this.size <= 1) {
+ return;
+ }
+
+ Node cur = headNode.next, innerCur, pre = headNode;
+ while(null != cur) {
+ E curItem = cur.item;
+
+ innerCur = headNode;
+ while(null != innerCur && cur != innerCur) {
+ if(innerCur.item.equals(curItem)) {
+ break;
+ } else {
+ innerCur = innerCur.next;
+ }
+ }
+
+ if(innerCur != null && cur != innerCur && innerCur.item.equals(cur.item)) {
+ pre.next = cur.next;
+ cur = cur.next;
+ } else {
+ pre = cur;
+ cur = cur.next;
+ }
+ }
+
+ }
+
+
+ /**
+ * 给定一个没有排序的链表,去掉其重复项 , 并保留原顺序,
+ * 例如链表 1->3->1->5->5->7,
+ * 去掉重复项后变为 1->3->5->7
+ *
+ * 递归法
+ */
+ public void removeRepeatItemFromUnorderedListM2(){
+ if(size <= 1) {
+ return;
+ }
+
+ removeRepeatItemByRecursion(this.headNode);
+ }
+
+ public void removeRepeatItemByRecursion(Node node) {
+ if(null == node || null == node.next ) {
+ return;
+ } else {
+ removeRepeatItemByRecursion(node.next);
+
+ Node next = node.next, pre=node;
+ while(null != next) {
+ if(node.item.equals(next.item)) {
+ pre.next = next.next;
+ break;
+ }
+
+ pre = next;
+ next = next.next;
+ }
+ }
+ }
+
+
+ /**
+ * 给定一个有序的链表,去掉其重复项 , 并保留原顺序,
+ * 例如链表 1->3->3->5->5->7,
+ * 去掉重复项后变为 1->3->5->7
+ *
+ */
+ public void removeRepeatItemFromOrderedListM1(){
+ if(this.size <= 1) {
+ return;
+ }
+
+ Node cur = headNode.next, pre= headNode;
+ while(cur != null) {
+ if(cur.item.equals(pre.item)) {
+ pre.next = cur.next;
+ } else {
+ pre = cur;
+ }
+ cur = cur.next;
+ }
+ }
+ private static class Node {
+ E item;
+ Node next;
+
+ Node(E element, Node next) {
+ this.item = element;
+ this.next = next;
+ }
+ }
+
+
+ public static void main(String[] args) {
+ SingleLinkedList list = new SingleLinkedList<>(2);
+
+ list.add(2);
+ list.add(2);
+ list.add(3);
+ list.add(3);
+ list.add(3);
+ list.add(5);
+ list.add(5);
+ list.add(7);
+ list.add(7);
+
+ list.printList();
+ list.removeRepeatItemFromOrderedListM1();
+ list.printList();
+ }
+
+
+}
+
diff --git a/src/com/gw/myalgo/gctest/FullGCTest.java b/src/com/gw/myalgo/gctest/FullGCTest.java
new file mode 100644
index 00000000..ad4682e1
--- /dev/null
+++ b/src/com/gw/myalgo/gctest/FullGCTest.java
@@ -0,0 +1,15 @@
+package com.gw.myalgo.gctest;
+
+public class FullGCTest {
+ public static void main(String[] args) {
+ byte[] array1 = new byte[4 * 1024 * 1024];
+ array1 = null;
+
+ byte[] array2 = new byte[2 * 1024 * 1024];
+ byte[] array3 = new byte[2 * 1024 * 1024];
+ byte[] array4 = new byte[2 * 1024 * 1024];
+ byte[] array5 = new byte[128 * 1024];
+
+ byte[] array6 = new byte[2 * 1024 * 1024];
+ }
+}
diff --git a/src/com/gw/myalgo/gctest/GCTest.java b/src/com/gw/myalgo/gctest/GCTest.java
new file mode 100644
index 00000000..ce0faeb8
--- /dev/null
+++ b/src/com/gw/myalgo/gctest/GCTest.java
@@ -0,0 +1,12 @@
+package com.gw.myalgo.gctest;
+
+public class GCTest {
+ public static void main(String[] args) {
+ byte[] array1 = new byte[1024 * 1024];
+ array1 = new byte[1024 * 1024];
+ array1 = new byte[1024 * 1024];
+ array1 = null;
+
+ byte[] array2 = new byte[2 * 1024 * 1024];
+ }
+}
diff --git a/src/com/gw/myalgo/gctest/GCTest1.java b/src/com/gw/myalgo/gctest/GCTest1.java
new file mode 100644
index 00000000..b0d8588f
--- /dev/null
+++ b/src/com/gw/myalgo/gctest/GCTest1.java
@@ -0,0 +1,14 @@
+package com.gw.myalgo.gctest;
+
+public class GCTest1 {
+ public static void main(String[] args) {
+ byte[] array1 = new byte[2 * 1024 * 1024];
+ array1 = new byte[2 * 1024 * 1024];
+ array1 = new byte[2 * 1024 * 1024];
+
+ byte[] array2 = new byte[128 * 1024];
+ array2 = null;
+
+ byte[] array3 = new byte[2 * 1024 * 1024];
+ }
+}
diff --git a/src/com/gw/myalgo/gctest/JstatTest.java b/src/com/gw/myalgo/gctest/JstatTest.java
new file mode 100644
index 00000000..e5939c9d
--- /dev/null
+++ b/src/com/gw/myalgo/gctest/JstatTest.java
@@ -0,0 +1,18 @@
+package com.gw.myalgo.gctest;
+
+public class JstatTest {
+ public static void main(String[] args) throws InterruptedException {
+ Thread.sleep(30000); // main线程休眠30s,以便jstat命令通过PID观察
+ while (true) {
+ loadData();
+ }
+ }
+ private static void loadData() throws InterruptedException {
+ byte[] data = null;
+ for (int i = 0; i < 50; i++) {
+ data = new byte[100 * 1024]; // 100KB
+ }
+ data = null;
+ Thread.sleep(1000); // 模拟上述操作全部发生在1s内
+ }
+}
diff --git a/src/com/gw/myalgo/gctest/JstatTest2.java b/src/com/gw/myalgo/gctest/JstatTest2.java
new file mode 100644
index 00000000..60d66e6c
--- /dev/null
+++ b/src/com/gw/myalgo/gctest/JstatTest2.java
@@ -0,0 +1,30 @@
+package com.gw.myalgo.gctest;
+
+/**
+ * -XX:NewSize=209715200 -XX:MaxNewSize=209715200 -XX:InitialHeapSize=314572800 -XX:MaxHeapSize=314572800 -XX:SurvivorRatio=2 -XX:MaxTenuringThreshold=15 -XX:PretenureSizeThreshold=20971520 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc-jstat2.log
+ */
+public class JstatTest2 {
+ public static void main(String[] args) throws InterruptedException {
+ Thread.sleep(30000); // main线程休眠30s,以便jstat命令通过PID观察
+
+ while (true) {
+ loadData();
+ }
+ }
+
+ private static void loadData() throws InterruptedException {
+ byte[] data = null;
+ for (int i = 0; i < 4; i++) {
+ data = new byte[10 * 1024 * 1024]; // 10MB
+ }
+ data = null;
+
+ byte[] data1 = new byte[10 * 1024 * 1024];
+ byte[] data2 = new byte[10 * 1024 * 1024];
+
+ byte[] data3 = new byte[10 * 1024 * 1024];
+ data3 = new byte[10 * 1024 * 1024];
+
+ Thread.sleep(1000); // 模拟上述操作全部发生在1s内
+ }
+}
diff --git a/src/com/gw/myalgo/gctest/VolatileTest.java b/src/com/gw/myalgo/gctest/VolatileTest.java
new file mode 100644
index 00000000..d0e556db
--- /dev/null
+++ b/src/com/gw/myalgo/gctest/VolatileTest.java
@@ -0,0 +1,30 @@
+package com.gw.myalgo.gctest;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+public class VolatileTest {
+ public static AtomicInteger t = new AtomicInteger(0);
+
+ public static void main(String[] args) throws InterruptedException {
+
+ int tnum = 10;
+ Thread[] threads = new Thread[tnum];
+ for(int i = 0; i < tnum; i++){
+ //每个线程对t进行1000次加1的操作
+ threads[i] = new Thread(() -> {
+ for(int j = 0; j < 1000; j++){
+ t.incrementAndGet();
+ }
+ System.out.println(Thread.currentThread().getName() + " is over");
+ });
+ threads[i].start();
+ }
+
+ Thread.sleep(1000);
+
+ //打印t的值
+ System.out.println(t);
+ }
+}
+
diff --git a/src/com/gw/myalgo/juc/AbstractTest.java b/src/com/gw/myalgo/juc/AbstractTest.java
new file mode 100644
index 00000000..4d49030c
--- /dev/null
+++ b/src/com/gw/myalgo/juc/AbstractTest.java
@@ -0,0 +1,8 @@
+package com.gw.myalgo.juc;
+
+public abstract class AbstractTest {
+
+ public static void main(String[] args) {
+ System.out.println("Abstract class can still be executed");
+ }
+}
diff --git a/src/com/gw/myalgo/sort/SortAlgo.java b/src/com/gw/myalgo/sort/SortAlgo.java
new file mode 100644
index 00000000..4d5a62a3
--- /dev/null
+++ b/src/com/gw/myalgo/sort/SortAlgo.java
@@ -0,0 +1,181 @@
+package com.gw.myalgo.sort;
+
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * @author hsden
+ */
+public class SortAlgo {
+
+ /**
+ * Bubble sort
+ * @param arr
+ */
+ public static void bubbleSort(int[] arr) {
+ if(null == arr || 0 == arr.length){
+ return ;
+ }
+
+ int i, j, tmp;
+ for(i = 0; i < arr.length - 1; i++){
+ for(j = 0; j < arr.length - i - 1; j++){
+ if(arr[j] > arr[j+1]){
+ tmp = arr[j];
+ arr[j] = arr[j+1];
+ arr[j+1] = tmp;
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Select sort
+ * @param arr
+ */
+ public static void selectSort(int[] arr) {
+ if(null == arr || 1 >= arr.length){
+ return;
+ }
+
+
+ for(int i = 0; i < arr.length -1; i++){
+ int smallestIdx = i;
+ for(int j = i + 1; j < arr.length; j++) {
+ if(arr[smallestIdx] > arr[j]) {
+ smallestIdx = j;
+ }
+ }
+
+ int tmp = arr[i];
+ arr[i] = arr[smallestIdx];
+ arr[smallestIdx] = tmp;
+ }
+ }
+
+ /**
+ * 2-way select sort
+ * @param arr
+ */
+ public static void selectSortUpdate(int[] arr) {
+ if(null == arr || 1 >= arr.length){
+ return;
+ }
+
+ for(int i = 0; i <= arr.length/2 ; i++){
+ int minIdx = i, maxIdx = i;
+ for(int j = i + 1; j < arr.length - i; j++) {
+ if(arr[minIdx] >= arr[j]) {
+ minIdx = j;
+ }
+
+ if(arr[maxIdx] <= arr[j]) {
+ maxIdx = j;
+ }
+ }
+
+ if(minIdx != i) {
+ int tmp = arr[i];
+ arr[i] = arr[minIdx];
+ arr[minIdx] = tmp;
+ if(maxIdx == i){
+ maxIdx = minIdx;
+ }
+ }
+
+ int n = arr.length -i -1;
+ if(maxIdx != n) {
+ int tmp = arr[n];
+ arr[n] = arr[maxIdx];
+ arr[maxIdx] = tmp;
+ }
+
+ printArr(arr);
+ }
+ }
+
+
+ /**
+ * Insert sort
+ * @param arr
+ */
+ public static void insertSort(int[] arr){
+ if(null == arr || 1 >= arr.length){
+ return;
+ }
+
+ for(int i = 1; i < arr.length; i++){
+ if(arr[i-1] > arr[i]) {
+ int j, tmp=arr[i];
+ for (j = i - 1; j >= 0; j--) {
+ if (arr[j] < tmp) {
+ break;
+ } else {
+ arr[j + 1] = arr[j];
+ }
+ }
+
+ arr[j + 1] = tmp;
+ }
+ }
+
+ }
+
+
+ /**
+ * Shell sort
+ * @param arr
+ */
+ public static void shellSortMain(int[] arr){
+
+ if(null == arr || 1 >= arr.length){
+ return;
+ }
+
+ int segment = arr.length/2;
+ while(segment >= 1){
+ shellInsertSort(arr,segment);
+ segment = segment/2;
+ }
+ }
+
+ public static void shellInsertSort(int[] arr, int dk){
+ if(null == arr || 1 >= arr.length || 0 >= dk){
+ return;
+ }
+
+ for(int i=dk; i < arr.length; ++i) {
+ if(arr[i] < arr[i -dk]) {
+ int j = i -dk, x=arr[i];
+ arr[i]=arr[j];
+ while(j >= 0 && x < arr[j]){
+ arr[j+dk] = arr[j];
+ j -= dk;
+ }
+ arr[j+dk] = x;
+ }
+ }
+ }
+
+ public static void printArr(int[] arr){
+ StringBuilder sb = new StringBuilder();
+ for(int value : arr){
+ sb.append(value + ",");
+ }
+ System.out.println(sb.substring(0, sb.length() - 1));
+ }
+
+ public static void main(String[] args) {
+ //5,7,9,10,2,32,4,4,3
+ int[] sortedArr = new int[]{5,7,9,10,2,32,4,4,3};
+ printArr(sortedArr);
+ //bubbleSort(sortedArr);
+ //selectSort(sortedArr);
+ selectSortUpdate(sortedArr);
+ //insertSort(sortedArr);
+ //shellSortMain(sortedArr);
+
+ printArr(sortedArr);
+ }
+}
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