diff --git a/src/main/java/algorithms/TreeSearch.java b/src/main/java/algorithms/TreeSearch.java index fa8bdce..71ab478 100644 --- a/src/main/java/algorithms/TreeSearch.java +++ b/src/main/java/algorithms/TreeSearch.java @@ -1,6 +1,6 @@ package algorithms; -import utils.TreeNode; +import datastructs.adt.utils.TreeNode; import utils.IPredicate; /** diff --git a/src/main/java/datastructs/adt/AVLTree.java b/src/main/java/datastructs/adt/AVLTree.java new file mode 100644 index 0000000..913dc2e --- /dev/null +++ b/src/main/java/datastructs/adt/AVLTree.java @@ -0,0 +1,34 @@ +package datastructs.adt; + + +import datastructs.adt.utils.ITreeBalance; + +import java.util.Comparator; + +/** + * Models an AVL Binary Search Tree + */ +public class AVLTree extends BinarySearchTree{ + + public AVLTree(Comparator comparator, ITreeBalance balancer){ + + super(comparator); + this.treeBalance = balancer; + } + + + /** + * Push a new element in the ADT + */ + @Override + public void push(E element){ + + // call the base class function to do the insertion + super.push(element); + + // now re-balance the tree + treeBalance.balance(this.getRoot()); + } + + private ITreeBalance treeBalance; +} diff --git a/src/main/java/datastructs/adt/BinarySearchTree.java b/src/main/java/datastructs/adt/BinarySearchTree.java index a02a3bd..b2e2563 100644 --- a/src/main/java/datastructs/adt/BinarySearchTree.java +++ b/src/main/java/datastructs/adt/BinarySearchTree.java @@ -1,9 +1,6 @@ package datastructs.adt; -import utils.BSTInsertStratergy; -import utils.IPredicate; -import utils.TreeNode; -import utils.TreeNodeCreator; +import datastructs.adt.utils.BSTInsertStratergy; import java.util.Comparator; @@ -26,18 +23,17 @@ public class BinarySearchTree extends BinaryTree { @Override public void push(E element){ - if(super.root_ == null){ + if(super.root == null){ this.createRoot(element); } else { - boolean rslt = super.getInsertStrategy().insert(super.root_, super.root_, element, null); + boolean rslt = super.getInsertStrategy().insert(super.root, super.root, element, null); if(rslt) { - super.nNodes_++; + super.nNodes++; } } - } } diff --git a/src/main/java/datastructs/adt/BinaryTree.java b/src/main/java/datastructs/adt/BinaryTree.java index d951a97..b1e37c7 100644 --- a/src/main/java/datastructs/adt/BinaryTree.java +++ b/src/main/java/datastructs/adt/BinaryTree.java @@ -1,5 +1,8 @@ package datastructs.adt; +import datastructs.adt.utils.ITreeInsertStrategy; +import datastructs.adt.utils.TreeNode; +import datastructs.adt.utils.TreeNodeCreator; import utils.*; public class BinaryTree extends Tree { @@ -18,13 +21,13 @@ public BinaryTree(ITreeInsertStrategy insertStrategy){ */ public void push(E element){ - if(super.root_ == null){ + if(super.root == null){ this.createRoot(element); } else { - boolean rslt = super.insertStrategy_.insert(super.root_, null, element, new IPredicate>() { + boolean rslt = super.treeInsertStrategy.insert(super.root, null, element, new IPredicate>() { @Override public boolean satisfies(TreeNode data) { return (data == null); @@ -32,7 +35,7 @@ public boolean satisfies(TreeNode data) { }); if(rslt) { - super.nNodes_++; + super.nNodes++; } } @@ -45,8 +48,8 @@ public boolean satisfies(TreeNode data) { protected void createRoot(E element){ TreeNodeCreator creator = new TreeNodeCreator<>(); - super.root_ = creator.create(element, null, 0, 2); - super.nNodes_++; + super.root = creator.create(element, null, 0, 2); + super.nNodes++; } diff --git a/src/main/java/datastructs/adt/RingBuffer.java b/src/main/java/datastructs/adt/RingBuffer.java new file mode 100644 index 0000000..a3b18ed --- /dev/null +++ b/src/main/java/datastructs/adt/RingBuffer.java @@ -0,0 +1,54 @@ +package datastructs.adt; + +import java.lang.reflect.Array; + +/** + * A ring buffer is an array together with read and write operations that wrap around. That is, when the + * last position of the array is reached, writing continues at the begin of the array, thereby erasing the oldest + * entries. The read operation starts at the oldest entry in the array. + */ +public class RingBuffer { + + + /** + * Constructor + */ + public RingBuffer(int capacity){ + + if(capacity <=0 ){ + throw new IllegalArgumentException("RingBuffer capacity should be greater than 0"); + } + + this.capacity = capacity; + this.elements = new Object[capacity]; + } + + + public long capacity(){ + return this.capacity; + } + + /** + * Returns the number of the number of elements in the buffer + * @return + */ + public long size(){ + return this.size; + } + + + /** + * The items of the buffer + */ + Object[] elements; + + /** + * How many elements the buffer can store + */ + long capacity; + + /** + * How many entries are currently in the buffer + */ + long size; +} diff --git a/src/main/java/datastructs/adt/Tree.java b/src/main/java/datastructs/adt/Tree.java index d7d1ecb..ee1a196 100644 --- a/src/main/java/datastructs/adt/Tree.java +++ b/src/main/java/datastructs/adt/Tree.java @@ -1,8 +1,8 @@ package datastructs.adt; -import utils.ITreeInsertStrategy; -import utils.TreeNode; +import datastructs.adt.utils.ITreeInsertStrategy; +import datastructs.adt.utils.TreeNode; /** * Base class for trees @@ -21,49 +21,52 @@ public abstract class Tree implements IAdt { * Returns how many elements the ADT has */ @Override - public final int size(){return this.nNodes_;} + public final int size(){return this.nNodes;} /** * Return the insertion strategy for the node */ public final ITreeInsertStrategy getInsertStrategy() { - return insertStrategy_; + return this.treeInsertStrategy; } + /** + * The insertion strategy to be used + */ public final void setInsertStrategy(ITreeInsertStrategy insertStrategy) { - this.insertStrategy_ = insertStrategy; + this.treeInsertStrategy = insertStrategy; } /** * Returns the root node of the tree */ - public TreeNode getRoot() { return root_; } + public TreeNode getRoot() { return this.root; } /** * Constructor */ protected Tree(ITreeInsertStrategy insertStrategy) { - this.insertStrategy_ = insertStrategy; + this.treeInsertStrategy = insertStrategy; } /** * The root of the tree */ - protected TreeNode root_ = null; + protected TreeNode root = null; /** * How many nodes the Tree has */ - protected int nNodes_ = 0; + protected int nNodes = 0; /** * Insert strategy for the tree */ - protected ITreeInsertStrategy insertStrategy_; + protected ITreeInsertStrategy treeInsertStrategy; } diff --git a/src/main/java/datastructs/adt/utils/AVLTreeBalancer.java b/src/main/java/datastructs/adt/utils/AVLTreeBalancer.java new file mode 100644 index 0000000..cb6e8bc --- /dev/null +++ b/src/main/java/datastructs/adt/utils/AVLTreeBalancer.java @@ -0,0 +1,8 @@ +package datastructs.adt.utils; + +public class AVLTreeBalancer implements ITreeBalance { + + public void balance(NodeType nodeType){ + + } +} diff --git a/src/main/java/utils/BSTInsertStratergy.java b/src/main/java/datastructs/adt/utils/BSTInsertStratergy.java similarity index 89% rename from src/main/java/utils/BSTInsertStratergy.java rename to src/main/java/datastructs/adt/utils/BSTInsertStratergy.java index 2a13c00..1f2bc5e 100644 --- a/src/main/java/utils/BSTInsertStratergy.java +++ b/src/main/java/datastructs/adt/utils/BSTInsertStratergy.java @@ -1,4 +1,6 @@ -package utils; +package datastructs.adt.utils; + +import utils.IPredicate; import java.util.Comparator; @@ -21,7 +23,7 @@ public BSTInsertStratergy(Comparator comparator){ * the calling site the newly created node */ public boolean insert(TreeNode root, TreeNode parent, E data, - IPredicate> insertPosPredicate){ + IPredicate> insertPosPredicate){ if(comparator.compare(data, parent.getData()) == 1){ diff --git a/src/main/java/utils/DfsInsertStrategy.java b/src/main/java/datastructs/adt/utils/DfsInsertStrategy.java similarity index 97% rename from src/main/java/utils/DfsInsertStrategy.java rename to src/main/java/datastructs/adt/utils/DfsInsertStrategy.java index e17f833..21aeedf 100644 --- a/src/main/java/utils/DfsInsertStrategy.java +++ b/src/main/java/datastructs/adt/utils/DfsInsertStrategy.java @@ -1,6 +1,7 @@ -package utils; +package datastructs.adt.utils; +import utils.*; public class DfsInsertStrategy implements ITreeInsertStrategy { diff --git a/src/main/java/datastructs/adt/utils/ITreeBalance.java b/src/main/java/datastructs/adt/utils/ITreeBalance.java new file mode 100644 index 0000000..c918d9e --- /dev/null +++ b/src/main/java/datastructs/adt/utils/ITreeBalance.java @@ -0,0 +1,9 @@ +package datastructs.adt.utils; + +/** + * General interface for providing balancing algorithms for trees + */ +public interface ITreeBalance { + + void balance(NodeType node); +} diff --git a/src/main/java/utils/ITreeInsertStrategy.java b/src/main/java/datastructs/adt/utils/ITreeInsertStrategy.java similarity index 90% rename from src/main/java/utils/ITreeInsertStrategy.java rename to src/main/java/datastructs/adt/utils/ITreeInsertStrategy.java index 66cb402..83cd4c1 100644 --- a/src/main/java/utils/ITreeInsertStrategy.java +++ b/src/main/java/datastructs/adt/utils/ITreeInsertStrategy.java @@ -1,4 +1,6 @@ -package utils; +package datastructs.adt.utils; + +import utils.IPredicate; /** * Insertion strategy for trees diff --git a/src/main/java/utils/TreeInsertMethod.java b/src/main/java/datastructs/adt/utils/TreeInsertMethod.java similarity index 66% rename from src/main/java/utils/TreeInsertMethod.java rename to src/main/java/datastructs/adt/utils/TreeInsertMethod.java index b22b674..dd3c8ad 100644 --- a/src/main/java/utils/TreeInsertMethod.java +++ b/src/main/java/datastructs/adt/utils/TreeInsertMethod.java @@ -1,4 +1,4 @@ -package utils; +package datastructs.adt.utils; public enum TreeInsertMethod { diff --git a/src/main/java/utils/TreeNode.java b/src/main/java/datastructs/adt/utils/TreeNode.java similarity index 98% rename from src/main/java/utils/TreeNode.java rename to src/main/java/datastructs/adt/utils/TreeNode.java index f4a3c85..d44d9fb 100644 --- a/src/main/java/utils/TreeNode.java +++ b/src/main/java/datastructs/adt/utils/TreeNode.java @@ -1,4 +1,4 @@ -package utils; +package datastructs.adt.utils; import java.util.ArrayList; diff --git a/src/main/java/utils/TreeNodeCreator.java b/src/main/java/datastructs/adt/utils/TreeNodeCreator.java similarity index 79% rename from src/main/java/utils/TreeNodeCreator.java rename to src/main/java/datastructs/adt/utils/TreeNodeCreator.java index e750509..a99e104 100644 --- a/src/main/java/utils/TreeNodeCreator.java +++ b/src/main/java/datastructs/adt/utils/TreeNodeCreator.java @@ -1,4 +1,6 @@ -package utils; +package datastructs.adt.utils; + +import datastructs.adt.utils.TreeNode; public class TreeNodeCreator { diff --git a/src/test/java/datastructs/AllDataStructsTestsRunner.java b/src/test/java/datastructs/AllDataStructsTestsRunner.java index f29a944..2e5fe87 100644 --- a/src/test/java/datastructs/AllDataStructsTestsRunner.java +++ b/src/test/java/datastructs/AllDataStructsTestsRunner.java @@ -19,8 +19,9 @@ public static void run(String[] args){ ArrayQueueTestRunner.run(args); SingleLinkedListTestRunner.run(args); BinaryTreeTestRunner.run(args); + AVLTreeTestRunner.run(args); MatrixDataSetTestRunner.run(args); - + RingBufferTestRunner.run(args); } public static void main(String[] args) { diff --git a/src/test/java/datastructs/adt/AVLTreeTest.java b/src/test/java/datastructs/adt/AVLTreeTest.java new file mode 100644 index 0000000..1fc12ef --- /dev/null +++ b/src/test/java/datastructs/adt/AVLTreeTest.java @@ -0,0 +1,59 @@ +package datastructs.adt; + +import datastructs.adt.utils.AVLTreeBalancer; +import org.junit.Ignore; +import org.junit.Test; + +import java.util.Comparator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class AVLTreeTest { + + static Comparator getComparator(){ + return (Integer a, Integer b)->{ + if( a.equals(b)){ + return 0; + } + else if( a.intValue() > b.intValue()){ + return 1; + } + + return -1; + }; + } + + /** + * Test Scenario: Application inserts a new node that violates the AVL property + * Expected Output: AVL property should be restored with single rotatio + */ + @Test + @Ignore + public void testSingleRotation(){ + + AVLTree tree = new AVLTree(AVLTreeTest.getComparator(), new AVLTreeBalancer()); + tree.push(3); + + assertNotNull("Root node was not created", tree.getRoot()); + assertEquals("Invalid root node data", tree.getRoot().getData().intValue(), 3); + + //add a second node + tree.push(2); + + assertNotNull("Child node was not created", tree.getRoot().getChild(0)); + assertEquals("Invalid root node data", tree.getRoot().getChild(0).getData().intValue(), 2); + + //this insertion should cause re-balancing + //add a second node + tree.push(1); + + assertNotNull("Root node was not created", tree.getRoot()); + assertEquals("Invalid root node data", tree.getRoot().getData().intValue(), 2); + assertNotNull("Left Child node was not created", tree.getRoot().getChild(0)); + assertEquals("Invalid left child data", tree.getRoot().getChild(0).getData().intValue(), 1); + assertNotNull("Right child node was not created", tree.getRoot().getChild(1)); + assertEquals("Invalid right child data", tree.getRoot().getChild(0).getData().intValue(), 3); + + } +} diff --git a/src/test/java/datastructs/adt/AVLTreeTestRunner.java b/src/test/java/datastructs/adt/AVLTreeTestRunner.java new file mode 100644 index 0000000..9eab702 --- /dev/null +++ b/src/test/java/datastructs/adt/AVLTreeTestRunner.java @@ -0,0 +1,35 @@ +package datastructs.adt; + +import org.junit.runner.JUnitCore; +import org.junit.runner.Result; +import org.junit.runner.notification.Failure; + +public class AVLTreeTestRunner { + + public static void run(String[] args){ + + System.out.println("============================"); + System.out.println("Start executing AVLTree tests"); + + Result result = JUnitCore.runClasses(AVLTreeTest.class); + + if( !result.wasSuccessful()) { + for (Failure failure : result.getFailures()) { + System.out.println(failure.toString()); + } + } + else{ + System.out.println("\tAll tests passed: "+ result.getRunCount()); + } + + System.out.println("\tTest run time: "+ result.getRunTime()); + System.out.println("Done...."); + System.out.println("============================"); + + } + + public static void main(String[] args) { + + AVLTreeTestRunner.run(args); + } +} diff --git a/src/test/java/datastructs/adt/BinarySearchTreeTest.java b/src/test/java/datastructs/adt/BinarySearchTreeTest.java index 897413b..769b12c 100644 --- a/src/test/java/datastructs/adt/BinarySearchTreeTest.java +++ b/src/test/java/datastructs/adt/BinarySearchTreeTest.java @@ -1,7 +1,7 @@ package datastructs.adt; import org.junit.Test; -import utils.TreeNode; +import datastructs.adt.utils.TreeNode; import java.util.Comparator; import static org.junit.Assert.assertEquals; diff --git a/src/test/java/datastructs/adt/BinaryTreeTest.java b/src/test/java/datastructs/adt/BinaryTreeTest.java index 941ac59..e876833 100644 --- a/src/test/java/datastructs/adt/BinaryTreeTest.java +++ b/src/test/java/datastructs/adt/BinaryTreeTest.java @@ -1,8 +1,8 @@ package datastructs.adt; -import utils.DfsInsertStrategy; +import datastructs.adt.utils.DfsInsertStrategy; import org.junit.Test; -import utils.TreeNode; +import datastructs.adt.utils.TreeNode; import static junit.framework.Assert.*; diff --git a/src/test/java/datastructs/adt/RingBufferTest.java b/src/test/java/datastructs/adt/RingBufferTest.java new file mode 100644 index 0000000..52a45c1 --- /dev/null +++ b/src/test/java/datastructs/adt/RingBufferTest.java @@ -0,0 +1,16 @@ +package datastructs.adt; + +import org.junit.Test; + +public class RingBufferTest { + + /** + * Test Scenario: The application attempts to initialize a RingBuffer with + * invalid number of elements + * Expected Output: IllegalArgumentException should be thrown + */ + @Test(expected = IllegalArgumentException.class) + public void testInvalidSizeBuffer(){ + RingBuffer buffer = new RingBuffer(-1); + } +} diff --git a/src/test/java/datastructs/adt/RingBufferTestRunner.java b/src/test/java/datastructs/adt/RingBufferTestRunner.java new file mode 100644 index 0000000..bc11c8e --- /dev/null +++ b/src/test/java/datastructs/adt/RingBufferTestRunner.java @@ -0,0 +1,35 @@ +package datastructs.adt; + +import org.junit.runner.JUnitCore; +import org.junit.runner.Result; +import org.junit.runner.notification.Failure; + +public class RingBufferTestRunner { + + public static void run(String[] args){ + + System.out.println("============================"); + System.out.println("Start executing RingBuffer tests"); + + Result result = JUnitCore.runClasses(RingBufferTest.class); + + if( !result.wasSuccessful()) { + for (Failure failure : result.getFailures()) { + System.out.println(failure.toString()); + } + } + else{ + System.out.println("\tAll tests passed: "+ result.getRunCount()); + } + + System.out.println("\tTest run time: "+ result.getRunTime()); + System.out.println("Done...."); + System.out.println("============================"); + + } + + public static void main(String[] args) { + + RingBufferTestRunner.run(args); + } +}