Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/main/java/datastructs/adt/BinarySearchTree.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package datastructs.adt;

import utils.BSTInsertStratergy;
import utils.IPredicate;
import utils.TreeNode;
import utils.TreeNodeCreator;

import java.util.Comparator;

/**
* Implementation of a Binary Search Tree
*/
public class BinarySearchTree<E> extends BinaryTree<E> {

/**
* Constructor
*/
BinarySearchTree(Comparator<E> comparator){
super(new BSTInsertStratergy(comparator));
}


/**
* Push a new element in the ADT
*/
@Override
public void push(E element){

if(super.root_ == null){

this.createRoot(element);
}
else {

boolean rslt = super.getInsertStrategy().insert(super.root_, super.root_, element, null);

if(rslt) {
super.nNodes_++;
}
}

}
}
19 changes: 15 additions & 4 deletions src/main/java/datastructs/adt/BinaryTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@ public BinaryTree(ITreeInsertStrategy insertStrategy){
/**
* Push a new element in the ADT
*/
public final void push(E element){
public void push(E element){

if(super.root_ == null){

TreeNodeCreator<E> creator = new TreeNodeCreator<>();
super.root_ = creator.create(element, null, 0, 2);
super.nNodes_++;
this.createRoot(element);
}
else {

Expand All @@ -40,6 +38,19 @@ public boolean satisfies(TreeNode<E> data) {

}

/**
* Create the root element
* @param element
*/
protected void createRoot(E element){

TreeNodeCreator<E> creator = new TreeNodeCreator<>();
super.root_ = creator.create(element, null, 0, 2);
super.nNodes_++;
}




/**
* Recursively add the element at the first null entry that is
Expand Down
49 changes: 49 additions & 0 deletions src/main/java/utils/BSTInsertStratergy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package utils;

import java.util.Comparator;

/**
*
*/
public class BSTInsertStratergy<E> implements ITreeInsertStrategy<E> {


/**
* Constructor
*/
public BSTInsertStratergy(Comparator<E> comparator){
this.comparator = comparator;
}

/**
* Insert a new node with the given data in the tree having the given root which has the given parent
* The insertion position is meant to satisfy the given predicate. It returns to
* the calling site the newly created node
*/
public boolean insert(TreeNode<E> root, TreeNode<E> parent, E data,
IPredicate<TreeNode<E>> insertPosPredicate){

if(comparator.compare(data, parent.getData()) == 1){

parent.setChild(1 , new TreeNode<>(data, parent, 2));
return true;
}
else if(comparator.compare(data, parent.getData() ) == -1){
parent.setChild(0 , new TreeNode<>(data, parent, 2));
return true;
}

return false;
}

/**
* Returns the type of the insert
*/
public TreeInsertMethod type(){return TreeInsertMethod.BST; }


/**
* The object used for comparisons
*/
Comparator<E> comparator;
}
4 changes: 2 additions & 2 deletions src/main/java/utils/DfsInsertStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@



public class DfsInsertStrategy implements ITreeInsertStrategy {
public class DfsInsertStrategy<E> implements ITreeInsertStrategy<E> {

@Override
public final TreeInsertMethod type(){return TreeInsertMethod.DFS; }

@Override
public final <DataTp> boolean insert(TreeNode<DataTp> root, TreeNode<DataTp> parent, DataTp data, IPredicate<TreeNode<DataTp>> insertPosPredicate){
public final boolean insert(TreeNode<E> root, TreeNode<E> parent, E data, IPredicate<TreeNode<E>> insertPosPredicate){

return doInsert(root, parent, data, insertPosPredicate).first;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/utils/ITreeInsertStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
/**
* Insertion strategy for trees
*/
public interface ITreeInsertStrategy {
public interface ITreeInsertStrategy<E> {

/**
* Insert a new node with the given data in the tree having the given root which has the given parent
* The insertion position is meant to satisfy the given predicate. It returns to
* the calling site the newly created node
*/
<DataTp> boolean insert(TreeNode<DataTp> root, TreeNode<DataTp> parent, DataTp data, IPredicate<TreeNode<DataTp>> insertPosPredicate);
boolean insert(TreeNode<E> root, TreeNode<E> parent, E data, IPredicate<TreeNode<E>> insertPosPredicate);

/**
* Returns the type of the insert
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/utils/TreeInsertMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

public enum TreeInsertMethod {

DFS, BFS
DFS, BFS, BST, INVALID
}
29 changes: 29 additions & 0 deletions src/main/java/utils/TreeNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,41 @@ public TreeNode(E data, TreeNode<E> parent, int level, int nChildren){
}
}


/**
* Create a node with the specified data and the given father
*/
public TreeNode(E data, TreeNode<E> parent, int nChildren){

this.data_ = data;
this.parent_ = parent;
this.level_ = 0;

if(parent != null){
this.level_ = parent.getLevel() + 1;
}

if(nChildren >=1) {
this.children_ = new ArrayList<TreeNode<E>>(nChildren);
}

for(int c=0; c < nChildren; ++c){
this.children_.add(null);
}
}

/**
* Set the data of the node
*/
public final void setData(E data){this.data_ = data;}


/**
* Returns the data stored by the node
*/
public final E getData(){return this.data_; }


/**
* Return the number of children the node has
*/
Expand Down
35 changes: 35 additions & 0 deletions src/test/java/datastructs/adt/BinarySearchTreeRunner.java
Original file line number Diff line number Diff line change
@@ -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 BinarySearchTreeRunner {

public static void run(String[] args){

System.out.println("============================");
System.out.println("Start executing BinarySearchTree tests");

Result result = JUnitCore.runClasses(BinarySearchTreeTest.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) {

BinarySearchTreeRunner.run(args);
}
}
49 changes: 49 additions & 0 deletions src/test/java/datastructs/adt/BinarySearchTreeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package datastructs.adt;

import org.junit.Test;
import utils.TreeNode;

import java.util.Comparator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class BinarySearchTreeTest {


/**
* Test Scenario: Application creates BST and attempts to insert an item larger than the root
* Exepected Output: Item should be properly insert at the right subtree of the root
*/
@Test
public final void testPushLargerThanRoot(){

Comparator<Integer> comparator = (Integer a, Integer b)->{
if( a.equals(b)){
return 0;
}
else if( a.intValue() > b.intValue()){
return 1;
}

return -1;
};

BinarySearchTree<Integer> tree = new BinarySearchTree<>(comparator);

// insert an item
tree.push(10);

TreeNode<Integer> root = tree.getRoot();
assertEquals("Invalid tree size", tree.size(), 1);
assertNotNull("Root node is null", root);

// this should be inserted at the right sub tree
tree.push(15);

assertEquals("Invalid tree size", tree.size(), 2);

TreeNode<Integer> rChild = root.getChild(1);
assertNotNull("Right child node is null", rChild);
assertEquals("Invalid right child data", rChild.getData().intValue(), 15);
}
}