Im trying to test a java generic class that i wrote, this is my test
public class BSTTest
{
public void testInsert()
{
int height;
BST<int> myTree = new BST<int>();
myTree.insert(1);
}
}
but when i compile i get the error of unexpected type, it says if found an int but requires a reference on the line of BST myTree = new BST(); what does that mean?
below are my Binary search tree and node class for reference
public class BST<E extends Comparable<E>>
{
public Node<E> root;
public BST()
{
root = null;
}
//insert delete find height
public void find(E s, Node<E> n)
{
//empty tree, root is null
if(n == null)
{
System.out.println("Item not present.");
}
//n is the node where s is, return n
else if(n.getData().equals(s))
{
System.out.println("Item present");
}
//s is greater than n, look for s on the right subtree
else if(s.compareTo(n.getData()) > 0)
{
find(s, n.getRight());
}
//s is less than n, look for s on the left subtree
else
{
find(s, n.getLeft());
}
}
public int height()
{
int count;
return count = height(root);
}
private int height(Node<E> n)
{
int ct = 0;
if(n == null)
{
}
else
{
int left = height(n.getLeft());
int right = height(n.getRight());
ct = Math.max(left, right) + 1;
}
return ct;
}
public void insert(E s)
{
root = insert(s, root);
}
private Node<E> insert(E s, Node<E> T)
{
//easiest case, empty tree, create new tree
if(T == null)
{
T = new Node<E>(s,null,null);
}
//easiest case, found s
else if(s.compareTo(T.getData()) == 0)
{
System.out.println("Item already present.");
}
//s is greater than T, insert on right subtree
else if(s.compareTo(T.getData()) > 0)
{
T.setRight(insert(s, T.getRight()));
}
//s is less than T, insert on left subtree
else
{
T.setLeft(insert(s,T.getLeft()));
}
return T;
}
public void delete(E d)
{
}
}
and my node class
public class Node<E>
{
private E data;
private Node<E> left;
private Node<E> right;
private Node<E> parent;
public Node(E d, Node<E> r, Node<E> l)
{
data = d;
left = l;
right = r;
}
public void setData(E d)
{
data = d;
}
public E getData()
{
return data;
}
public Node<E> getRight()
{
return right;
}
public void setRight(Node<E> nd)
{
right = nd;
}
public Node<E> getLeft()
{
return left;
}
public void setLeft(Node<E> nd)
{
left = nd;
}
public Node<E> getParent()
{
return parent;
}
public void setParent(Node<E> nd)
{
parent = nd;
}
}
Can you try Integer instead of int?
Generic type takes only Classes (Object types) and not the primite data type
It should be
BST<Integer> myTree = new BST<Integer>();
Java generics are only for Object types. Since, int is a primitive type you cannot use it. Instead use BST<Integer>
You can't use a primitive type like int as a parameter to a generic class in Java. It has to be a class type, such as Integer.
Related
An abstract binary tree is to be created using a generic class. Each node has a string value as well as an initialCalculatedValue value. No changes should be made to the main class and a static inner class is to be included in the generic class. I'd like some advice on my code, as the main class is giving me error on accessing 'timesVisited' and 'values'. My code can't seem to access those variables.
Main class code:
public class Main{
public static void main(String[] args) {
WalkableTree<String, Integer> ast = new WalkableTree<>(0);
WalkableTree.Node<String, Integer> plus = ast.setRoot("+");
plus.setRightChild("20");
WalkableTree.Node<String, Integer> multiply = plus.setLeftChild("*");
multiply.setLeftChild("10");
WalkableTree.Node<String, Integer> bracketedPlus = multiply.setRightChild("+");
bracketedPlus.setLeftChild("3");
bracketedPlus.setRightChild("4");
// write visitor to display pre-order
System.out.println("Pre-order traversal:");
ast.walk(current -> {
if(current.timesVisited == 2)
System.out.print(current.value + " ");
});
System.out.println();
// write visitor to display in-order
System.out.println("In-order traversal:");
ast.walk(current -> {
if(current.timesVisited == 3)
System.out.print(current.value + " ");
});
System.out.println();
// write visitor to display post-order
System.out.println("Post-order traversal:");
ast.walk(current -> {
if(current.timesVisited == 4)
System.out.print(current.value + " ");
});
System.out.println();
}
}
Functional interface:
#FunctionalInterface
public interface Visitor<N> {
public void visit(N node);
}
Generic class:
public class WalkableTree <T, R> {
private T root = null;
private R initialCalculatedValue;
public static Node current;
public WalkableTree(R initialCalculatedValue) {
this.initialCalculatedValue = initialCalculatedValue;
}
public Node getRoot() {
return (Node) root;
}
public Node setRoot(T value) {
current = new Node(null,null,null,value,null,0);
return current;
}
public R getInitialCalculatedValue() {
return initialCalculatedValue;
}
public void setInitialCalculatedValue(R initialCalculatedValue) {
this.initialCalculatedValue = initialCalculatedValue;
}
protected void reset(Node node) {
node.timesVisited = 0;
node.calculatedValue = initialCalculatedValue;
reset((Node) node.leftChild);
reset((Node) node.rightChild);
}
public Node nextNode(Node node) {
node.timesVisited++;
if(node.timesVisited == 1)
return node;
if(node.timesVisited == 2)
return (Node) node.leftChild;
if(node.timesVisited == 3)
return (Node) node.rightChild;
if(node.timesVisited == 4)
return (Node) node.getParent();
return node;
}
public void walk(Visitor visitor) {
//Reset all the nodes in the tree
reset((Node) root);
//Set the current node to visit at the root of the tree
visitor.visit(root);
//Walking through the tree as long as the current node still exists
//If current node exists, let the visitor object visit the current node
//Current node is set to the next node using nextNode() method
while (this.current == current)
{
nextNode(current);
}
}
public static class Node<T, R> {
//Variables
Object leftChild;
Object rightChild;
Object parent;
T value;
R calculatedValue;
int timesVisited = 0;
public Node(Object leftChild, Object rightChild, Object parent, T value, R calculatedValue, int timesVisited) {
this.leftChild = leftChild;
this.rightChild = rightChild;
this.parent = parent;
this.value = value;
this.calculatedValue = calculatedValue;
this.timesVisited = timesVisited;
}
public Object getLeftChild() {
return leftChild;
}
public Node setLeftChild(T value) {
Node newLeft = new Node(null,null, current,value,0,0);
current = newLeft;
return current;
}
public Object getRightChild() {
return rightChild;
}
public Node setRightChild(T value) {
Node newRight = new Node(null,null, current,value,0,0);
current = newRight;
return current;
}
public Object getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public R getCalculatedValue() {
return calculatedValue;
}
public void setCalculatedValue(R calculatedValue) {
this.calculatedValue = calculatedValue;
}
public int getTimesVisited() {
return timesVisited;
}
public void setTimesVisited(int timesVisited) {
this.timesVisited = timesVisited;
}
}
}
Update the method in WalkableTree as below:
public void walk(Visitor<Node> visitor) {
//Reset all the nodes in the tree
reset((Node) root);
//Set the current node to visit at the root of the tree
visitor.visit((Node) root);
//Walking through the tree as long as the current node still exists
//If current node exists, let the visitor object visit the current node
//Current node is set to the next node using nextNode() method
while (this.current == current)
{
nextNode(current);
}
}
I am getting this mystical error:
The operator > is undefined for the argument type(s)
java.lang.Comparable, java.lang.Comparable
What the heck?
(here's the code)
public class BST<T extends Comparable<T>> {
public static class Node<P extends Comparable<P>> {
P val;
Node<P> left;
Node<P> right;
public Node() {
}
public Node(P val) {
this.val = val;
}
}
Node<T> root;
private void addValHelper(Node root, Node newNode) {
if (root.val > newNode.val) { // <-- ERROR IS HERE
if (root.left == null) {
root.left = newNode;
} else {
addValHelper(root.left, newNode);
}
} else {
if (root.right == null) {
root.right = newNode;
} else {
addValHelper(root.right, newNode);
}
}
}
}
Java doesn't have operator overloading. You can't compare Comparable types with >. You need to use root.val.compareTo(newNode.val) instead.
As an aside:
Comparable is an interface, not a class
You don't need to specify <P extends Comparable<P>>
It might make more sense to move the addValHelper code into the Node class itself
It might make sense for Node to implement Comparable.
This way, your code feels a lot more idiomatic and you don't expose fields of Node to BST.
public class BST<T implements Comparable<T>> {
private final Node<T> root;
/** Presumably this is run when a value is added.. */
private void addValueHelper(Node rootNode, Node newNode) {
rootNode.attachChild(newNode);
}
public static class Node implements Comparable<T> {
private final T val;
private Node left;
private Node right;
public Node(T val) {
this.val = val;
}
public int compareTo(Node other) {
return this.val.compareTo(other.val);
}
/**
* Takes the given node and compares it with the current node.
* If the current node is greater than the given node, the given node is placed to the left.
* Otherwise it is placed to the right.
*/
protected void attachChild(Node newNode) {
if (this.compareTo(newNode) == 1) {
if (this.left == null) {
this.left = newNode;
return;
}
this.left.attachChild(newNode);
return;
}
if (this.right == null) {
this.right = newNode;
return;
}
this.right.attachChild(newNode);
}
}
}
I created a binary tree using templates. I entered integer values for all the nodes and I want to find the maximum element in the Binary Tree.
Here is the implementation:
public class BinaryTreeNode<T> {
private T data;
BinaryTreeNode right;
BinaryTreeNode left;
public BinaryTreeNode(T data) {
this.data = data;
this.right = null;
this.left = null;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public BinaryTreeNode getRight() {
return right;
}
public void setRight(BinaryTreeNode right) {
this.right = right;
}
public BinaryTreeNode getLeft() {
return left;
}
public void setLeft(BinaryTreeNode left) {
this.left = left;
}
public int findMax(BinaryTreeNode root){
int max= 0;
if(root==null){
return 0;
} else {
int left= findMax(root.left);
int right= findMax(root.right);
max= Math.max(left,right);
if(max> root.getData()){
max= root.getData();
}
return max;
}
}
}
I am getting the following errors:
incompatible types: required int found java.lang.Object.
I wrote this in the modified version:
int data= Integer.valueOf((String)root.getData());
Is there a better way to do it?
root.getData() has a generic type T. This means you can't assume it will be an Integer, you can't determine which of two nodes has a higher value using Math.max() and findMax() should return T, not an int.
In order to find the max element, you must either require that T extends Comparable<T>, which will allow you to compare the data of two BinaryTreeNodes using compareTo(), or you should pass a Comparator<T> instance to the constructor of your tree, which will allow you to compare the data of BinaryTreeNodes using compare().
You must also avoid using the raw type BinaryTreeNode. Replace it will BinaryTreeNode<T> in all your methods. Otherwise, method call such as root.getData() will return an Object instead of T.
Using Comparable:
public class BinaryTreeNode<T extends Comparable<T>>
{
...
public T findMax(BinaryTreeNode<T> root) {
T max = null;
if(root == null) {
return null;
} else {
T left = findMax(root.left);
T right = findMax(root.right);
max = left.compareTo(right) <= 0 ? right : left;
if(max.compareTo(root.getData()) < 0) {
max = root.getData();
}
return max;
}
}
...
}
So the idea is to make a Double Ended Priority Queue so far I have got a tree like structure using 2 Linked Lists, I have and interface I have to stick with with no alterations to it. The problem I have got is I have to make 2 methods called getMost and getLeast which gets the most or least node and then makes that node null. But these 2 methods are proving quite difficult to make. How would you go about doing it?
I have tried using recursion but this is proving difficult as I have to select the tree by going tree.root but passing in tree.root into a recursive method always starts it from tree.root
Also I have tried what i have written in inspectLeast() and inspectMost() but Java passes by value not by reference. Any tips?
P.S Not allowed to use anything from java collections or java util.
public class PAS43DPQ implements DPQ
{
//this is the tree
TreeNode tree = new TreeNode();
//this is for the size of the array
int size = 0;
#Override
public Comparable inspectLeast() {
return tree.inspectLeast(tree.root);
}
#Override
public Comparable inspectMost() {
return tree.inspectMost(tree.root);
}
#Override
public void add(Comparable c)
{
tree.add(c);
size++;
}
#Override
public Comparable getLeast() {
if (tree.root != null){
}
return getLeast();
}
#Override
public Comparable getMost(){
Comparable most = getMost();
return most;
}
#Override
public boolean isEmpty() {
return (size > 0)?true:false;
}
#Override
public int size() {
return this.size;
}
class TreeNode{
private Comparable value;
private TreeNode left, right, root;
//constructors
public TreeNode() {}
public TreeNode(TreeNode t) {
this.value = t.value;
this.left = t.left;
this.right = t.right;
this.root = t.root;
}
public TreeNode(Comparable c) {
this.value = (int) c;
}
public void add(Comparable input){
if(root == null){
root = new TreeNode(input);
return;
} else {
insert(root, input);
}
}
public Comparable inspectLeast(TreeNode n){
if (n == null)
return null;
if (n.left == null){
TreeNode least = n;
return least.value;
}
return inspectLeast(n.left);
}
public Comparable inspectMost(TreeNode n){
if (n == null)
return null;
if (n.right == null){
TreeNode most = n;
return most.value;
}
return inspectMost(n.right);
}
public Comparable getMost(TreeNode n){
if(n.right == null)
return n.value;
return tree.getMost(right);
}
public void insert(TreeNode n, Comparable input){
if(input.compareTo(n.value) >= 0){
if (n.right == null) {
n.right = new TreeNode(input);
return;
}
else
insert(n.right, input);
}
if(input.compareTo(n.value) < 0){
if(n.left == null) {
n.left = new TreeNode(input);
return;
}
else
insert(n.left, input);
}
}
}
}
You should be able to modify your TreeNode.getMost(TreeNode n) and TreeNode.getLeast(TreeNode n) similar to the following:
public class TreeNode{
// Also, your parameter here seems to be superfluous.
public TreeNode getMost(TreeNode n) {
if (n.right == null) {
n.root.right = null;
return n;
}
return n.getMost(n);
}
}
Get least should be able to be modified in a similar fashion, but using left rather than right obviously.
Im new to generics and i have to implement a binary search tree using generics. I did that but now im wondering how do i test the code that i wrote? Do i just make another class and start using the methods of the bst?
any help would be appreciated. below is my code just to clarify.
public class BST<E extends Comparable<E>>
{
public Node<E> root;
public BST()
{
root = null;
}
//insert delete find height
public void find(E s, Node<E> n)
{
//empty tree, root is null
if(n == null)
{
System.out.println("Item not present.");
}
//n is the node where s is, return n
else if(n.getData().equals(s))
{
System.out.println("Item present");
}
//s is greater than n, look for s on the right subtree
else if(s.compareTo(n.getData()) > 0)
{
find(s, n.getRight());
}
//s is less than n, look for s on the left subtree
else
{
find(s, n.getLeft());
}
}
public int height()
{
int count;
return count = height(root);
}
private int height(Node<E> n)
{
int ct = 0;
if(n == null)
{
}
else
{
int left = height(n.getLeft());
int right = height(n.getRight());
ct = Math.max(left, right) + 1;
}
return ct;
}
public void insert(E s)
{
root = insert(s, root);
}
private Node<E> insert(E s, Node<E> T)
{
//easiest case, empty tree, create new tree
if(T == null)
{
T = new Node<E>(s,null,null);
}
//easiest case, found s
else if(s.compareTo(T.getData()) == 0)
{
System.out.println("Item already present.");
}
//s is greater than T, insert on right subtree
else if(s.compareTo(T.getData()) > 0)
{
T.setRight(insert(s, T.getRight()));
}
//s is less than T, insert on left subtree
else
{
T.setLeft(insert(s,T.getLeft()));
}
return T;
}
public void delete(E d)
{
}
}
and my node class
public class Node<E>
{
private E data;
private Node<E> left;
private Node<E> right;
private Node<E> parent;
public Node(E d, Node<E> r, Node<E> l)
{
data = d;
left = l;
right = r;
}
public void setData(E d)
{
data = d;
}
public E getData()
{
return data;
}
public Node<E> getRight()
{
return right;
}
public void setRight(Node<E> nd)
{
right = nd;
}
public Node<E> getLeft()
{
return left;
}
public void setLeft(Node<E> nd)
{
left = nd;
}
public Node<E> getParent()
{
return parent;
}
public void setParent(Node<E> nd)
{
parent = nd;
}
}
Im trying to follow what you said, this is my test class
public class BSTTest
{
public void testInsert()
{
int height;
BST myTree = new BST();
myTree.insert(1);
}
}
but when i compile i get the error of unexpected type, it says if found an int but requires a reference on the line of BST myTree = new BST(); what does that mean?
Yes, make a class called BSTTest and create methods to test each of the public methods in BST.
If you use JUnit, you can use annotations and a standard naming convention
public class BSTTest {
#Test
public void testInsert() {
BST<String> bst = new BST<String>();
String s = "hello";
bst.insert(s);
AssertTrue("I should get back what I put in!", bst.find(s));
}
#Test
public void testDelete() {
// etc...
}
}
Then, you can run this 'Unit Test' in your java IDE (such as IntelliJ IDEA) or, if you have it set up, via maven: mvn test.
Also, I think your find() method could return boolean?
good luck!