I have this thing
Comparator.java
public interface Comparator<T> {
public int compareTo(int num);
}
valueComparator.java
public class valueComparator implements Comparator<Tree.Node> {
#Override
public int compareTo(Tree.Node obj, int number) {
if (obj.getDataNumber() == number) {
return 0;
}
else if (obj.getDataNumber() < number) {
return -1;
}
else return 1;
}
}
Tree.java
public class Tree {
public Node root;
Tree() {
}
public static class Node {
Node(int number, String str, boolean flag) {
dataNumber = number;
dataText = str;
dataBool = flag;
}
public int getDataNumber() {
return this.dataNumber;
}
public String getDataText() {
return this.dataText;
}
public boolean getDataBool() {
return this.dataBool;
}
public void setDataText(String text) {
this.dataText = text;
}
public void isDataBool(boolean flag) {
this.dataBool = flag;
}
Node left;
Node right;
private int dataNumber;
private String dataText;
private boolean dataBool;
}
public void binaryTree() {
root = null;
}
public boolean search(int number) {
return search(root, number);
}
valueComparator comp = new valueComparator();
private boolean search(Node node, int number) {
if (node == null) {
return false;
}
if (comp.compareTo(node, number) == 0) {
return true;
}
if (comp.compareTo(node, number) == -1) {
return search(node.left, number);
}
else {
return search(node.right, number);
}
}
public void insertLeaf(int number, String str, boolean flag) {
root = insertLeaf(root, number, str, flag);
}
private Node insertLeaf(Node node, int number, String str, boolean flag) {
if (node == null) {
node = new Node(number, str, flag);
} else {
if (number < node.dataNumber) {
node.left = insertLeaf(node.left, number, str, flag);
}
else if (number > node.dataNumber) {
node.right = insertLeaf(node.right, number, str, flag);
}
else {
System.out.println("The element is already in the tree.");
}
}
return node;
}
}
Test.java
public class Test {
public static void main(String args[]) {
Tree binTree = new Tree();
binTree.binaryTree();
binTree.insertLeaf(5, "text2", true);
binTree.insertLeaf(4, "text4", false);
binTree.insertLeaf(1, "text1", true);
binTree.insertLeaf(3, "text3", true);
binTree.insertLeaf(2, "text5", false);
System.out.println("Element 3 found: " + binTree.search(3));
// Element 3 found: false
}
}
I am supposed to do the search with a comparator, but I fail to understand the logic. The compareTo method works for itself but it stucks at the recursive call of search. After the first pass, if the return of compareTo is not = 0, then it enters with null and breaks out of recursion and returns false. Meaning if I set the first element of the tree to be '3', the search(3) will return true, but if it's different than 3 - false and won't even look for it in the tree.
When you insert a number you compare it directly to the nodes' values and if the number is less than the value stored in the current node, you follow the left pointer.
However when you search for a number, you use a comparator, which compares the node's value to the number given (note the opposite order!) and if the number is less than the value in the current node, you follow a right link.
Use either direct comparision or a comparator, as you wish – but use the same method everywhere.
Related
Hi,
Update: Thanks for all your suggestion
assuming that, this exercise it's like a rebus,
I have a list of numbers made with the concept of Cons and Nil,
List l = new Cons(**3**, new Cons(**2**,new Cons(**1**, new
Cons(**4**, new Cons(**1**, new Nil())))));
and I want to count how many of them are immediately followed by a lower number, recursively.
For example
[5,0,5,3].count() == 2, [5,5,0].count() == 1
The count() method is made by me (it cannot have any parameters), the rest is default, and I can't make and other method or use already defined one's like add(),size()...
The "NEXT" must have the next value after the current elem but I can't get a solution.
Any solutions are welcome.
abstract class List {
public abstract boolean empty();
public abstract int first();
public abstract int count();
}
class Cons extends List {
private int elem;
private List next;
public Cons(int elem, List next) {
this.elem = elem;
this.next = next;
}
public boolean empty(){
return false;
}
public int first(){
return elem;
}
#Override
public int count() {
if(elem>NEXT) {
return 1 + next.count();
}else {
return next.count();
}
}
```
The following code will create a recursive list with N elements with N value being defined by the size of the amount of elements found in the int array called elements in RecursiveList class. Call the startRecursion() method to create a recursive list with the defined elements and call count() to get the amount of elements in the array that are immediately followed by a lower number.
Main Class
This your application entry point:
public static void main(String[] args) {
int count = RecursiveList.startRecursion().count();
System.out.printf("List has %d recursive elements", count);
}
RecursiveList Class
abstract class RecursiveList {
protected static int index = -1;
protected static int[] elements = new int[]{ 5,2,1,4,3,2,6 };
public static RecursiveList startRecursion() {
return new Cons();
}
public abstract boolean empty();
public abstract int count();
public abstract Integer getElement();
public static int incIndex() {
return index += 1;
}
}
Cons Class
public class Cons extends RecursiveList {
private static int result;
private final Integer elem;
private final RecursiveList prev;
private final RecursiveList next;
private Cons(Cons parent) {
prev = parent;
elem = incIndex() < elements.length ? elements[index] : null;
System.out.printf("Creating new Cons with element %d(%d)%n", elem, index);
next = elem != null ? new Cons(this) : null;
}
Cons() {
this(null);
}
public boolean empty() {
return false;
}
#Override
public /*#Nullable*/ Integer getElement() {
return elem;
}
#Override
public int count() {
if (elem != null)
{
if (prev != null && elem < prev.getElement())
result += 1;
if (next != null) {
return next.count();
}
}
return result;
}
}
EDIT
Alright here is the answer you were actually looking for. This completely conforms to the limitations imposed on this exercise that you provided. The solution uses pure Java, neither the class nor any of it's method or field declarations were modified in any way and no such new elements were added. I've only added the implementation where the exercise said you should.
Main Class
public static void main(String[] args) {
List l = new Cons(3, new Cons(2,new Cons(1, new
Cons(4, new Cons(1, new Nil())))));
assert l.count() == 3;
l = new Cons(5, new Nil());
assert l.count() == 0;
l = new Cons(5, new Cons(5, new Cons(0, new Nil())));
assert l.count() == 1;
l = new Cons(5, new Cons(0, new Cons(5, new Cons(3, new Nil()))));
assert l.count() == 2;
System.out.println("All tests completed successfully!");
}
Cons Class
import java.util.NoSuchElementException;
public class Cons extends List {
private int elem;
private List next;
public Cons(int elem, List next) {
this.elem = elem;
this.next = next;
}
public boolean empty()
{ return false; }
public int first()
{ return elem; }
public int count()
{
try {
if (first() > next.first()) {
return 1 + next.count();
}
else return next.count();
}
catch (NoSuchElementException e) {
return 0;
}
}
}
Nil Class
import java.util.NoSuchElementException;
public class Nil extends List {
public boolean empty()
{ return true; }
public int first()
{ throw new NoSuchElementException(); }
public int count()
{
throw new IllegalAccessError();
}
}
public int NEXT(){
if(next!=null)
return next.first()
else
throw new Exception("No next element")
}
I have the following classes and I want to let the user choose whether he wants to create a BST with integers or a BST with strings. How can i create a BST from integers when the user choose 5 or create a BST from strings when the user press 6? Also if anyone find something wrong with my generics pls let me know!
Thanks a lot
public class BSTNode <T extends Comparable<T>>
{
T value;
BSTNode<T> left;
BSTNode<T> right;
public BSTNode(T value, BSTNode<T> l,BSTNode<T> r)
{
this.value = value;
left = l;
right = r;
}
public BSTNode(T value)
{
this(value,null,null);
}
public T getValue()
{
return value;
}
public void setValue(T value)
{
this.value = value;
}
public BSTNode<T> getLeftChild()
{
return left;
}
public BSTNode<T> getRightChild()
{
return right;
}
public void setLeftChild(BSTNode<T> node)
{
left = node;
}
public void setRightChild(BSTNode<T> node)
{
right = node;
}
public boolean search(T value)
{
if (value.equals(this.value))
return true;
else if (value.compareTo(this.value) < 0)
{
if (left == null)
return false;
else
return left.search(value);
} else if (value.compareTo(this.value) > 0)
{
if (right == null)
return false;
else
return right.search(value);
}
return false;
}
public boolean add(T value)
{
if (value.compareTo(this.value)==0)
return false;
else if (value.compareTo(this.value) < 0)
{
if (left == null)
{
left = new BSTNode<T>(value);
return true;
} else
return left.add(value);
}
else if (value.compareTo(this.value) > 0)
{
if (right == null)
{
right = new BSTNode<T>(value);
return true;
}
else
return right.add(value);
}
return false;
}
public boolean remove(T value2, BSTNode<T> parent)
{
if (value2.compareTo(this.value)<0)
{
if (left != null)
return left.remove(value2, this);
else
return false;
}
else if (value2.compareTo(this.value)>0)
{
if (right != null)
return right.remove(value2, this);
else
return false;
}
else
{
if (left != null && right != null)
{
this.value = right.minValue();
right.remove(this.value, this);
}
else if (parent.left == this)
{
parent.left = (left != null) ? left : right;
}
else if (parent.right == this)
{
parent.right = (left != null) ? left : right;
}
return true;
}
}
public T minValue()
{
if (left == null)
return value;
else
return left.minValue();
}
}
public class BinarySearchTree <T extends Comparable<T>>
{
private BSTNode<T> root;
public BinarySearchTree(T value)
{
root = new BSTNode<T>(value);
}
public BSTNode getRoot()
{
return root;
}
public boolean search(T value)
{
if (root.equals(null))
return false;
else
return root.search(value);
}
public boolean add(T value)
{
if (root == null) {
root = new BSTNode(value);
return true;
} else
return root.add(value);
}
public boolean remove(T value) {
if (root == null)
return false;
else {
if (root.getValue() == value) {
BSTNode auxRoot = new BSTNode(null);
auxRoot.setLeftChild(root);
boolean result = root.remove(value, auxRoot);
root = auxRoot.getLeftChild();
return result;
} else {
return root.remove(value, null);
}
}
}
public static void displayInorder(BSTNode T)
{
if (T!=null)
{
if (T.getLeftChild()!=null)
{
displayInorder(T.getLeftChild());
}
System.out.print(T.getValue() + " ");
if(T.getRightChild()!=null)
{
displayInorder(T.getRightChild());
}
}
}
}
import java.util.Scanner;
public class main {
public static void main(String[] args) {
BinarySearchTree b = new BinarySearchTree(null);
boolean flag = true;
while (flag) {
Scanner scan = new Scanner(System.in);
System.out.println("Select 1 to add values in to BST\n"
+ "Select 2 to delete values from the BST \n"
+ "Select 3 to search for a value\n"
+ "Select 4 to display te values held in the BST\n"
+ "Select 5 to create a BST of strings\n"
+ "Select 6 to create a BST of integers\n"
+ "Select 7 to exit" );
int opt = scan.nextInt();
switch (opt) {
case 1: System.out.println("Insert the value of your choice: ");
String str = scan.next();
b.add(str);
break;
case 2: System.out.println("Insert the value of your choice: ");
str = scan.next();
b.remove( str);
break;
case 3:
System.out.println("Insert the value of your choice: ");
str = scan.next();
b.search(str);
break;
case 4:
BinarySearchTree.displayInorder(b.getRoot());
break;
case 5:
case 7:
flag=false;
break;
}
}
}
}
In order to get the most of generics in your code this is my suggestions:
I would add a method to process a string (the user input) into the appropriate type in the tree class:
...
import java.util.function.Function;
...
public class BinarySearchTree <T extends Comparable<T>>
{
private BSTNode<T> root;
private Function<String,T> valueDecoder
public BinarySearchTree(final Function<String,T> valueDecoder)
{
this.valueDecoder = valueDecoder;
root = new BSTNode<T>(null);
}
...
public boolean decodeAndAdd(final String encodedValue) {
return add(valueDecoder.apply(encodedValue));
}
public boolean decodeAndRemove(final String encodedValue) {
return remove(valueDecoder.apply(encodedValue));
}
}
```
Then you would leave the b variable undefined/null until you actually now the type of tree given the choice provided by the user. Since it might contain String or Integer here you can only use ? as the type parameter, perhaps ? extends Comparable<?> as that is part of the constraint... ? is fine in this case:
BinarySearchTree<?> b = null;
Now when the user ask for a String or Integer tree you need to provide the appropriate lambda to transfer the scanned string into the actual element value:
case 5:
b = new BinarySearchTree<>(scanStr -> scanStr);
break;
case 6:
b = new BinarySearchTree<>(scanStr -> Integer.parseInt(scanStr));
break;
Now add and remove are trivial:
case 1:
b.decodeAndAdd(scan.next());
break;
case 2:
b.decodeAndRemove(scan.next());
break;
If the user provides a non-valid integer string value when the tree is an Integer tree it would result in a NumberFormatException and the program would stop. Perhaps you would rather show an error message and allow the user to do another operator. For that:
case 6:
b = new BinarySearchTree<>(scanStr -> {
try {
return Integer.parseInt(scanStr);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("you must provide a valid integer value: '" + scanStr + "'");
}
});
break;
...
case 1:
try {
b.decodeAndAdd(scan.next());
} catch (final IllegalArgumentException ex) {
System.err.println("ERROR: " + ex.getMessage());
}
break;
case 2:
try {
b.decodeAndRemove(scan.next());
} catch (final IllegalArgumentException ex) {
System.err.println("ERROR: " + ex.getMessage());
}
break;
Perhaps is not ideal to add decodeAndAdd and decodeAndRemove to your BinarySearchTree class if you want to keep things a bit more modular as the BST might be used outside the user command line context described in the question.
In that case you could define a generic "struct" like class that contains a reference that contains a reference to the BST and the decoding lambda with their element type bound to be the same using a type-parameter. You could also extends the BST class in another user-interface specialized BST that add this functionality:
class CommandLineBST<T> {
public final BST<T> tree;
public final Function<String, T> valueDecoder;
public CommandLineBST(final BST<T> tree, final Function<String, T> decoder) {
this.tree = tree;
this.valueDecoder = decoder;
}
public boolean add(final String scanStr) {
return tree.add(valueDecoder.apply(scanStr));
}
public boolean remove(final String scanStr) {
return tree.remove(valueDecoder.apply(scanStr));
}
}
or
class CommandLineBST<T> extends BST<T> {
private Function<String, T> valueDecoder;
public CommandLineBST(final Function<String, T> valueDecoder) {
super(null);
this.valueDecoder = valueDecoder;
}
public boolean decodeAndAdd(final String scanStr) { ... }
public boolean decodeAndRemove(final String scanStr) { ... }
}
I have already put in the following methods for a binary search tree:
import java.util.Collections;
import java.util.NoSuchElementException;
import java.util.ArrayList;
public class MyTree {
private class Node
{
public String data;
public int data2;
public Node left;
public Node right;
public Node(String data, Node left, Node right)
{
this.data = data;
this.left = left;
this.right = right;
}
}
private static Node root = null;
private int getHeight(Node subroot)
{
if (subroot == null)
return -1;
int maxLeft = getHeight(subroot.left);
int maxRight = getHeight(subroot.right);
return Math.max(maxLeft, maxRight) + 1;
}
public String toString()
{
return toString(this.root);
}
private String toString(Node subroot)
{
if (subroot==null)
return "";
return toString(subroot.left)+subroot.data+toString(subroot.right);
}
public boolean containsRecursive(String value)
{
return contains(value, this.root);
}
private boolean contains(String value, Node subroot)
{
if (subroot==null)
return false;
else if (value.equals(subroot.data))
return true;
else if (value.compareTo(subroot.data) < 0)
return contains(value, subroot.left);
else
return contains(value, subroot.right);
}
public boolean contains(String value) // not recursive
{
Node subroot = this.root;
while (subroot != null)
{
if (value.equals(subroot.data))
return true;
else if (value.compareTo(subroot.data) < 0)
subroot = subroot.left;
else
subroot = subroot.right;
}
return false;
}
public int addUp()
{
return addUp(this.root);
}
private int addUp(Node subroot)
{
if (subroot==null)
return 0;
return addUp(subroot.left)+subroot.data2+addUp(subroot.right);
} //data = String, data2 = int
public int count()
{
return count(this.root);
}
private int count(Node subroot)
{
if (subroot==null)
return 0;
return count(subroot.left)+1+count(subroot.right);
}
public int numberLess(int x)
{
return numberLess(this.root, x);
}
private int numberLess(Node subroot, int x)
{
if (subroot==null)
return 0;
if (x < subroot.data2)
return numberLess(subroot.left, x)+1+numberLess(subroot.right, x);
return numberLess(subroot.left, x)+numberLess(subroot.right, x);
}
public int findMax()
{
return findMax(this.root);
}
private int findMax(Node subroot) throws NoSuchElementException
{
if (subroot==null)
throw new NoSuchElementException();
return Math.max(findMax(subroot.left), findMax(subroot.right));
}
private ArrayList<Integer> addToList(Node subroot, ArrayList<Integer> a)
{
if (subroot!=null){
a.add(subroot.data2);
addToList(subroot.left, a).addAll(addToList(subroot.right, a));
return a;
}
return new ArrayList<Integer>();
}
private ArrayList<Integer> getSortedList(){
ArrayList<Integer> rawList = addToList(this.root, new ArrayList<Integer>());
Collections.sort(rawList);
return rawList;
}
public void rebalance(){
ArrayList<Integer> list = getSortedList();
}
}
How can I finish the rebalance method using the structure I already have? I'd like to use the sorted arraylist by finding the midpoints and recursively ordering them. I'm not sure how this would be approached using the way I have my tree set up (with the internal node class) so I'd like some help with this code.
Split the array in two equal sized portions. Take the median element as new root node.
Then split again the two portions and take the median element as second level nodes, etc.
Best implemented recursively....
I'm having a problem with trying the logic and trying to write a min and additionMerge function and their recursive versions of the function that takes at least one list as an argument (the first node of the list). This will be a private helper function that is called by a wrapper function that is a member function of the LinkedList class.
public class LinkedList {
private static class ListNode {
public int firstItem;
public ListNode restOfList;
}
private ListNode first;
/**
* Create an empty list.
*/
public LinkedList() {
first = null;
}
public LinkedList(int n) {
first = countDown(n);
}
public LinkedList(String s) {
String[] temp = s.split(",");
for (int i = temp.length-1; i >= 0; i--) {
first = insertAtFront(first, Integer.parseInt(temp[i]));
}
}
public int length() {
return length(first);
}
private static int length(ListNode list) {
if (list == null) {
return 0;
}
int temp = length(list.restOfList);
return temp + 1;
}
public boolean contains(int value) {
return contains(first, value);
}
private static boolean contains(ListNode list, int value) {
if (list == null) {
return false;
}
if (list.firstItem == value) {
return true;
}
return contains(list.restOfList, value);
}
public int sum() {
return sum(first);
}
private static int sum(ListNode list) {
if (list == null) {
return 0;
}
return sum(list.restOfList) + list.firstItem;
}
public int count(int target) {
return count(first, target);
}
private static int count(ListNode list, int target) {
if (list == null) {
return 0;
}
int temp = count(list.restOfList, target);
if (list.firstItem == target) {
temp++;
}
return temp;
}
public void replace(int oldValue, int newValue) {
replace(first, oldValue, newValue);
}
private static void replace(ListNode list, int oldValue, int newValue) {
if (list == null) {
return;
}
replace(list.restOfList, oldValue, newValue);
if (list.firstItem == oldValue) {
list.firstItem = newValue;
}
}
public void insertAtFront(int n) {
first = insertAtFront(first, n);
}
private static ListNode insertAtFront(ListNode list, int n) {
ListNode answer = new ListNode();
answer.firstItem = n;
answer.restOfList = list;
return answer;
}
private static ListNode countDown(int n) {
if (n == 1) {
ListNode answer = new ListNode();
answer.firstItem = 1;
answer.restOfList = null;
return answer;
}
ListNode temp = countDown(n - 1);
ListNode answer = insertAtFront(temp, n);
return answer;
}
public void insertAtBack(int item) {
first = insertAtBack(first, item);
}
private static ListNode insertAtBack(ListNode list, int item) {
if (list == null) {
ListNode answer = new ListNode();
answer.firstItem = item;
answer.restOfList = null;
return answer;
}
//List answer = new ListNode();
//answer.firstItem = list.firstItem;
ListNode temp = insertAtBack(list.restOfList, item);
//answer.restOfList = temp;
list.restOfList = temp;
return list;
}
public void concatenate(LinkedList otherList) {
this.first = concatenate(this.first, otherList.first);
}
private static ListNode concatenate(ListNode list1, ListNode list2) {
if (list1 == null) {
return list2;
}
ListNode temp = concatenate(list1.restOfList, list2);
list1.restOfList = temp;
return list1;
}
public void filter(int item) {
first = filter(first, item);
}
#Override
public String toString() {
if (first == null) {
return "";
}
StringBuilder sb = new StringBuilder(256);
sb.append(first.firstItem);
for (ListNode current = first.restOfList;
current != null;
current = current.restOfList) {
sb.append(',');
sb.append(current.firstItem);
}
return sb.toString();
}
private static ListNode filter(ListNode list, int item) {
if (list == null) {
return null;
}
ListNode temp = filter(list.restOfList, item);
if (list.firstItem == item) {
return temp;
}
list.restOfList = temp;
return list;
}
public int min() throws RuntimeException {
if (first == null)
throw new RuntimeException("List is Empty");
else
return min();
}
// * A private recursive helper function that returns the minimum item in a
* list whose first node is the argument list.
private static int min(ListNode list) throws RuntimeException {
if (list == null) {
return 0;
}
}
public void additionMerge(LinkedList l2) {
}
* Every node in the list that begins with node
* node1 is increased by the ammount of the corresponding
* node in the list that begins with node node2.
* If one list is longer than the other, the missing nodes
* in the shorter list are assumed to be 0.
private static ListNode additionMerge(ListNode node1, ListNode node2) {
if (list == null) {
return null;
}
}
}
If this is not homework, then my advice is:
Don't write your own LinkedList class. Use the existing out, and add the extra functionality either as a helper class or by extending the existing class.
If you do decide to implement your own linked list class, then you should beware of using recursion. Recursion gives a neat soltion, but there is a major drawback with recursion in Java. The JVM does not do tail call optimization, so a recusive algorithm that recurses deeply (e.g. recursively traversing a long list) is liable to cause a StackOverflowError.
I'm having a little bit of difficulty with my insert method for this homework assignment. I have most of it done, but for some reason whenever my program is supposed to insert a node as a right child on the left side of the tree it just inserts it as a left child.
I kind of do my comparison in a weird way (signs should be reversed for a lot of them, but it worked like that for some reason) so please bear with me if you have difficulty in reading it.
I know that this is a horrible way to implement a binary search tree, and I would never ever do it in the real world, but it's homework and thus -- I have no choice.
Any and all help is appreciated, as always. Thank you!
Edit: I know where the problem is now. It's within the searchFor() method. Instead of the node's rightful parent, it makes the parent the root of the tree (in this case the parent of the node is always "cup".)
now that that's out of the way, can anyone offer up a solution?
Edit2: Took some of the extra stuff out that I don't think is relevant to the problem. I'm pretty sure I've narrowed it down to the searchFor() method. Whenever I call to return the parent of the current node, it will return the root of the tree ("cup.") I think that's why I'm having my problems, since it inserts based on that.
Thanks for all the help so far, I really appreciate it.
public class BinarySearchTree //implements Comparator
{
private Comparator<Object> dataComparator;
private LinkedListWithTwoLinks tree;
public static void main (String[] args)
{
BinarySearchTree bst;
Object hold;
String[] words = {"cup", "shaker", "cord", "key", "addressbook", "date", "address", "cupcake",
"card", "tape", "page", "day", "key", "days", "dayt"};
bst = new BinarySearchTree(new AlphabeticComparator());
System.out.println("[1]: original tree");
for(int i=0; i<words.length; i++) if (!bst.insert(words[i])) { System.out.println(">>>>>>>>>>>>> " + words[i] + " is already in tree"); }
bst.inOrder();
}
public static class AlphabeticComparator implements Comparator <Object>
{
public int compare(Object x, Object y)
{
if ( x == y ) return 0;
if ( x == null) return -1;
if ( y == null) return 1;
return (x.toString().compareTo(y.toString()));
}
}
public static class LastCharacterComparator implements Comparator <Object>
{
public int compare(Object x, Object y)
{
String xs;
String ys;
if ( x == y ) return 0;
if ( x == null ) return -1;
if ( y == null) return 1;
xs = x.toString();
ys = y.toString();
if ( xs.length() == 0) return -1;
if ( ys.length() == 0) return 1;
return (xs.charAt(xs.length()-1) - ys.charAt(ys.length()-1));
}
}
public BinarySearchTree(Comparator<Object> y)
{
dataComparator = y;
this.tree = new LinkedListWithTwoLinks();
}
private int compare(BinarySearchTreeElementInterface s, Object data)
{
return this.dataComparator.compare(s, data);
}
public boolean insert(Object data)
{
boolean success;
BinarySearchTreeElementInterface current;
BinarySearchTreeElementInterface parent;
current = getRoot();
parent = null;
success = false;
if (current == null)
{
getTree().insert(data);
return true;
}
else
{
SearchResult insert;
insert = searchFor(data);
//if (data == "shaker") {System.out.println(insert.resultOfCompare); }
while (current != null)
{
if (insert.insertAsLeftChild())
{
//if (data == "card") {System.out.println("IN RIGHT");}
//System.out.println("IN LEFT");
parent = current;
current = current.getLeftChild();
}
else if (insert.insertAsRightChild())
{
//if (data == "card") {System.out.println("IN RIGHT");}
parent = current;
current = current.getRightChild();
}
}
if (insert.insertAsLeftChild())
{
//parent.setLeftChild(insert.getParentOfLocation()); //insert.getParentOfLocation()
//System.out.println(data);
getTree().insertUsingPrior(parent, data);
//System.out.println(insert.getParentOfLocation()+" bye left");
// System.out.println(insert.getLocation()+" hi");
success = true;
}
else if (insert.insertAsRightChild())
{
//parent.setRightChild(insert.getParentOfLocation());
//System.out.println(data);
getTree().insertUsingNext(parent, data);
//System.out.println(insert.getParentOfLocation()+" bye right");
// System.out.println(insert.getLocation());
success = true;
}
else {success = false;}
/*
figures out if it should be inserted as a left or right child
then call insert using prior/next
}*/
}
return success;
}
private SearchResult searchFor(Object data)
{
/*returns either to node containing the data or the parent of the node of which the data would be a child of*/
if (getTree() == null) {throw new ListEmptyException("Tree is empty!");}
BinarySearchTreeElementInterface currentLocation;
BinarySearchTreeElementInterface parent;
SearchResult destination;
parent = getRoot();
currentLocation = parent;
while (currentLocation != null)
{
if (currentLocation.getData() == data)
{
return new SearchResult(parent, currentLocation, compare(currentLocation, data));
}
if (compare(currentLocation, data) < 0)
{
//System.out.println("IN LEFT");
parent = currentLocation;
currentLocation = currentLocation.getLeftChild();
}
else if (compare(currentLocation, data) > 0)
{
//System.out.println("IN RIGHT");
parent = currentLocation;
currentLocation = currentLocation.getRightChild();
}
}
destination = new SearchResult(parent, currentLocation, compare(parent, data));
//System.out.println(destination.resultOfCompare);
return destination;
/*
* use nothing but BSTEIs
*/
}
public void inOrder()
{
inOrder(getRoot());
}
public void inOrder(BinarySearchTreeElementInterface BSTroot)
{
//System.out.println(BSTroot.getRightChild());
if (BSTroot != null)
{
inOrder(BSTroot.getLeftChild());
System.out.println(BSTroot.getData());
inOrder(BSTroot.getRightChild());
}
/*if (BSTroot.getLeftChild() != null)
{
}
System.out.println(BSTroot.getData());
if (BSTroot.getRightChild() != null)
{
inOrder(BSTroot.getRightChild());
//System.out.println(BSTroot.getData());
}
System.out.println(BSTroot.getData());*/
}
public int size()
{
return tree.size();
}
/*SEARCH RESULT CLASS-----------------------------------------------------------------------------------------*/
public class SearchResult
{
BinarySearchTreeElementInterface location;
BinarySearchTreeElementInterface parentOfLocation;
int resultOfCompare;
public SearchResult(BinarySearchTreeElementInterface parent, BinarySearchTreeElementInterface locate, int comp)
{
this.parentOfLocation = parent;
this.location = locate;
this.resultOfCompare = comp;
}
public BinarySearchTreeElementInterface getLocation()
{
return this.location;
}
public BinarySearchTreeElementInterface getParentOfLocation()
{
return this.parentOfLocation;
}
public boolean insertAsLeftChild()
{
if (resultOfCompare > 0) {return true;}
else {return false;}
}
public boolean insertAsRightChild()
{
if (resultOfCompare < 0) {return true;}
else {return false;}
}
public boolean locationIsLeftOfParent()
{
return this.location == parentOfLocation.getLeftChild();
}
public boolean locationisRightOfParent()
{
return this.location == parentOfLocation.getRightChild();
}
public boolean wasSearchSuccessful()
{
return this.parentOfLocation == this.location;
}
public void setLocation(BinarySearchTreeElementInterface newLocation)
{
this.location = newLocation;
}
public void setLocationOfParent(BinarySearchTreeElementInterface newParentLocation)
{
this.parentOfLocation = newParentLocation;
}
}
}
compare(x, y) method of BinarySearchTree is wrong.
It compares a node to a data with a comparator made to compare data against data. Change 'Object' to 'String' and it will not compile while your sample data are strings.
This should fix it:
private int compare(BinarySearchTreeElementInterface s, Object data)
{
return this.dataComparator.compare(s.getData(), data);
}
In your SearchResult class, do you have the way it determines a left or right insert swapped?
public boolean insertAsLeftChild()
{
if (resultOfCompare > 0) {return true;}
else {return false;}
}
If the compare is greater than 0, it should be interested as a right child, correct?