I'm having trouble trying to figure out the following. Imagine that I have the generic class Node<T> for representing the nodes of a binary tree, with some methods in it.
public class Node<T> {
T info;
Node<T> left;
Node<T> right;
public Node(T info) {this.info=info;}
//and some methods
}
Now I would like to add a method for Nodes of type Integer, which would sum all the nodes that can be reached from the current one:
public int sum(){
int sum = this.info;
if(this.left!=null) sum+=left.sum();
if(this.right!=null) sum+=right.sum();
return sum;
}
I am not quite sure how to do this. I thought of creating a class that extends Node<Integer> and adding the method sum there:
public class NodeOfIntegers extends Node<Integer>{
public NodeOfIntegers (T info) {super();}
public int sum(){...}
}
but since left and right are of type Node<Integer> and not NodeOfIntegers I can't do left.sum() and right.sum().
Is there a way to do this without redefining left and right?
Thank you very much.
Use a reduce function like the Stream provides:
public static class Node<T>{
public Node(T value, Node<T> a, Node<T> b){
this.value = value;
this.a = a;
this.b = b;
}
private final Node<T> a,b;
private final T value;
private T reduce(T start,BinaryOperator<T> operator){
T reduced = operator.apply(start,value);
if(a != null)reduced = a.reduce(reduced,operator);
if(b != null)reduced = b.reduce(reduced,operator);
return reduced;
}
}
public static void main(String[] args) {
Node<Integer> integerNode = new Node<>(4,new Node<>(4,null,null),new Node<>(2,null,null));
System.out.println(integerNode.reduce(0, Integer::sum));
}
You should define your T as
class Node<T extends Number> {
}
then you can write the function of sum as
int sum() {
int sum = this.info.intValue();
}
Instead of using a NodeOfInteger class, I would define in the Node class a
public T combine(BinaryOperator<T> combiner) {
T res = this.info;
if (this.left != null) res = combine(res, this.left.combine(combiner);
if (this.right != null) res = combine(res, this.right.combine(combiner);
return res;
}
which can be used as node.combine(Integer::sum), or as node.combine(String::concat)
(Note that this can be defined outside of the Node class if needed)
Related
Consider the following definitions of BSTNode and BST classes:
public class BSTNode<T extends Comparable<? super T>> {
protected T el;
protected BSTNode<T> left, right;
public BSTNode() {
left = right = null;
}
public BSTNode(T el) {
this(el,null,null);
}
public BSTNode(T el, BSTNode<T> lt, BSTNode<T> rt) {
this.el = el; left = lt; right = rt;
}
}
public class BST<T extends Comparable<? super T>> {
protected BSTNode<T> root = null;
public BST() {
}
….
}
how can i implement a method in class BST to count the number of right children in a BST
To my understanding, the number of right children of a node can be counted recursively as follows.
First, implement a recursive method in the BSTNode class.
public int GetNumOfRightChildren()
{
int Result = 0;
if (null != right)
Result = 1 + right.GetNumOfRightChildren();
return Result;
}
Next, this method could be made accessible in a very similar way in the BST class as follows.
public int GetNumOfRightChildren()
{
int Result = 0;
if (null != root)
Result = 1 + root.GetNumOfRightChildren();
return Result;
}
If changing the implementation of BSTNode is not permitted, the task cannot be solved as the right and left subtrees in BSTNode are inaccessible from the BST class.
I am tasked with writing my own PriorityQueue class in Java. It is based on LinkedLists. To quote the directions:
The type of the data stored in the nodes should be a generic type that is comparable. That is write for the class declaration: public class PriorityQueue (E extends Comparable)) -> note: the curly braces are meant to mean <>, whatever I write between <> is disappearing...
I will be using the PriorityQueue to write two other classes, one of type patient, the other of waitingRoom. This is where the compareTo method will come into play, as I sort the two classes into their individual PriorityQueues.
I have been defining the ListNode class inside of the PriorityQueue class itself, so I have a class within a class. Now comes the question:
Where am I going to implement/Override the inherited compareTo method from Comparable?
It can't get implemented in the PriorityQueue class because compareTo can only take one argument. Yet, this is where it seems like it should go, as this is the actual class extending Comparable.
If I implement it inside the ListNode class, well, I have no idea how I would. Do I turn ListNode into an interface? An AbstractClass?
Below is the quite novice code I have written, thanks for the help
package hostpitalQueue;
import java.util.AbstractList;
public class PriorityQueue<E extends Comparable<E>> {
private ListNode front;
public PriorityQueue() {
front = null;
}
public PriorityQueue(ListNode n1) {
front = n1;
}
//method for addingNode to beginning,
//perhaps overload method for next nodes?
public void addNode(ListNode n1) {
if(front == null) {
front = n1;
}else {
//need to find last node and add n1 to it
ListNode lastNode = findLastNode(n1);
lastNode.addNode(n1);
}
}
//need to compare, remember, this is a priorityqueue
public ListNode findLastNode(ListNode n) {
//compare the data of both
//compare to front
ListNode n1 = front;
int i = n1.compareTo(n);
//only do something here if n is higher priority
if(i > 0) {
E frontData = n1.data;
E nodesData = n.data;
ListNode holder = n1;
front = n;
n.next = holder;
holder.previous = n;
}else if(n1.next == null) {
n1.next = n;
n.previous = n1;
}
else {
while(front.next != null) {
n1 = front.next;
//is n1 a higher priority?
Integer ii = n1.compareTo(n);
if(ii > 0) {
//this means that we should return the previous node, to insert
//before this one
return n1.previous;
}
}
}
return n1;
}
public class ListNode {
//contains a left and a right, as well as a data field
public E data;
public ListNode previous,next;
//construct
public ListNode() {
data = null;
previous = null;
next = null;
}
//previous to next
public ListNode(E data) {
this.data = data;
previous = null;
next = null;
}
public ListNode(E data,ListNode n1) {
this.data = data;
previous = n1;
next = null;
}
public ListNode(E data,ListNode n1,ListNode n2) {
this.data = data;
previous = n1;
next = n2;
}
public void addNode(ListNode n1) {
//gotta check if my next is null
ListNode holder = null;
if(this.next != null) {
holder = this.next;
}
this.next = n1;
n1.previous = this;
n1.next = holder;
}
public int compareTo(ListNode n1) {
return 0;
}
public void printMe() {
System.out.println(this.data);
}
}
}
Each class that you will use as element type of PriorityQueue must implement the Comparable interface and the compareTo method.
Note that as your ListNode class implements a compareTo method, you could have made it implement Comparable<ListNode>:
public class ListNode implements Comparable<ListNode> {
...
#Override
public int compareTo(ListNode n1) {
return data.compareTo(n1.data);
}
Note that as you ListNode classe doesn't depend on an instance of PriorityQueue, you could have made it static; in which case, you would have had to declare a generic argument:
public static class ListNode<T extends Comparable<T>>
implements Comparable<ListNode<T>> {
//contains a left and a right, as well as a data field
public T data;
public ListNode<T> previous,next;
//construct
public ListNode() {
data = null;
previous = null;
next = null;
}
//previous to next
public ListNode(T data) {
this.data = data;
previous = null;
next = null;
}
public ListNode(T data,ListNode<T> n1) {
this.data = data;
previous = n1;
next = null;
}
public ListNode(T data,ListNode<T> n1,ListNode<T> n2) {
this.data = data;
previous = n1;
next = n2;
}
public void addNode(ListNode<T> n1) {
//gotta check if my next is null
ListNode<T> holder = null;
if(this.next != null) {
holder = this.next;
}
this.next = n1;
n1.previous = this;
n1.next = holder;
}
#Override
public int compareTo(ListNode<T> n1) {
return data.compareTo(n1.data);
}
public void printMe() {
System.out.println(this.data);
}
}
class ListNode has fields, so you can't change it to an interface (why the hell would you do that anyway?)
You should perhaps ask yourself if you really need a doubly linked list and if a singly linked list would not suffice.
It is unclear in your question if you need to implement a linked list or if you could make use of the class LinkedList in which case you would not need the ListNode class: PriorityQueue would just encapsulate a LinkedList<E>.
If you are wanting to compare two ListNodes, as in the line:
n1.compareTo(n)
You'd need to make it implement Comparable:
public class ListNode implements Comparable<ListNode> {
And implement the compareTo method as something like:
return this.data.compareTo(that.data);
(since you know the data is Comparable). But you would have to handle the case of null data.
Note that you should also declare your type variable on the top-level class as:
<E extends Comparable<? super E>>
i am trying to implement the linkedList and i already implemented the addition of elements from the TreeSet and also the size of the List through recursion. Now i am trying to find the range of the list when we give the lower and upper bound and i want to implement it through recursion. here is the main class.
public static void main(String[] args) {
TreeSet<String> ts;
ts = new TreeSet<>();
ts.add("C");
ts.add("A");
ts.add("B");
ts.add("E");
ts.add("F");
ts.add("D");
ts.add("z");
LinkedList<String> l=new LinkedList<>(ts);
and here is the LinkedList Class
public class LinkedList<T extends Comparable<T>> {
private class Node {
private T data;
private Node next;
private Node(T data)
{
this.data = data;
next = null;
}
}
private Node head;
Node current=null;
int s=0;
public LinkedList() {
head=null;
}
public HashSet<T> inRange(T lowerBound, T upperBound)
{
if(head==null)
return null;
if(head.data.compareTo(lowerBound)==0)
{
set.add(head.data);
return inRange(lowerBound,head.next.data);
}
if(head.data.compareTo(upperBound)==0)
{
return set;
}
return set;
}
i think this is not a correct way but i will appreciate every help if someone helps me in making my code correct.
Thanks in advance.
I am new to generics and want to solve a little Task.
I want to give two Objects of type "V extends Comparable" to the class ComparePredicate and then check in method "isOk" if the int-value "value" of a Tree class is between these two Objects.
I choosed the compareTo method because Integer and V should be of type comparable but the compiler gives an error.
I think its just an syntactical problem.
So how do i need to write it correct. Hope you guys can help me.
Thanks for your answers.
Class ComparePredicate
public class ComparePredicate<V extends Comparable<V>> implements TreePredicate<V> {
V minEle;
V maxEle;
public ComparePredicate(V minEle, V maxEle) {
this.minEle = minEle;
this.maxEle = maxEle;
}
#Override
public boolean isOk(Tree<V> tree) {
return minEle.compareTo(Integer.valueOf(tree.getValue())) > 0 &&
maxEle.compareTo(Integer.valueOf(tree.getValue())) < 1;
//COMPILER ERROR: "The method compareTo(V) in the type Comparable<V> is not applicable for the arguments (Integer)"
return false;
}
}
Class Tree
public class Tree<T> {
private int value;
private final Tree<T> left;
private final Tree<T> right;
public Tree(int v, Tree<T> l, Tree<T> r) {
this.value = v;
this.left = l;
this.right = r;
}
public int getValue() {
return this.value;
}
public Tree<T> getLeft() {
return this.left;
}
public Tree<T> getRight() {
return this.right;
}
}
Change Tree class
static class Tree<T> {
private T value;
private final Tree<T> left;
private final Tree<T> right;
public Tree(T v, Tree<T> l, Tree<T> r) {
this.value = v;
this.left = l;
this.right = r;
}
public T getValue() {
return this.value;
}
// getters ...
}
And also change isOk()
#Override
public boolean isOk(Tree<V> tree) {
return minEle.compareTo(tree.getValue()) <= 0 &&
maxEle.compareTo(tree.getValue()) >= 0;
}
It's a homework problem. we need to build a method in java that clones a given binary search tree through recursion, ive looked up several examples online, the problem being that the program our instructor asked us to write was in what he called the Modern method, whereby rather than checking for null in each method, a tree is constructed using Dynamic dispatch from an Interface Node, connected to two subclasses nil(representing an empty node and the necessary methods to deal with an instance of an empty Node) and Vertex, a filled node and its affiliate methods. im confused on how to structure the recursion to clone the nodes, and construct the nodes to hold the cloned info. this being homework im obviously not looking for an answer but i really need some help with this.
interface Node<T extends Comparable<T>>
{
public int size();//return the number of values in the tree
public boolean empty();//true if tree is empty nil
public Node<T> insert(T x);// insert something into a binary search tree, return the node it was inserted into
public vertex<T> search(T x);//search for a given value and return the vertex ( filled node ) it exists in
public int depth();//returns the greatest depth of the tree
public void inorder();
//public Node<T> Attack_of_the_clones();
}
//note that insert must be used as in t = t.insert(x)
class nil<T extends Comparable<T>> implements Node<T> //empty tree
{
public int size() {return 0;}// empty node, therefore of size zero
public boolean empty() { return true; }//its and empty node, duh
public Node<T> insert(T x) { return new vertex<T>(x); }// returns a Tpe Node for inserting a given value into a node (thereby creating a
//vertex containing said inserted value)
public vertex<T> search (T x) { return null; }//RETURNS NULL IN SEARCHING FOR A GIVE VALUE BECAUSE NODES OF TPE nIL ARE INHERENTLY empty
public int depth() { return 0; }
public void inorder() { System.out.print("0");}
//public Node<T> Attack_of_the_clones() { return new nil<T>(this); }
}//end nil
class vertex<T extends Comparable<T>> implements Node<T>
{
protected T head;// the root of the tree
protected Node<T> left;//creates an instance of Node to serve as the left child of head
protected Node<T> right;
//constructor
public vertex(T h, Node<T> l, Node<T> r) { head = h; left = l; right = r; }// a constructed instance
//leaf instructor
public vertex(T h) { head = h; left = new nil<T>(); right = new nil<T>(); }//a constructed leaf
// a leaf is Tpically a node with no or null children, some consider the null nodes themselves to be leaves
//accesors so that the protected variables can be displayed
public T acHead() {return head;}
public Node<T> acLeft() {return left;}
public Node<T> acRight() {return right;}
public int size()
{
return left.size() + right.size() + 1;//recursively call size down the left and right trees to get all the nodes,
// and combine them ( +1 for the root) to get the size of the tree
}
public int depth()
{
return Math.max((left.depth()+1),(right.depth()+1));
}
public boolean empty() {return false; }//because its of class vertex and therefore not empty
public Node<T> insert(T x)
{
if (x.compareTo(head) <= 0)// go down left tree
left = left.insert(x);
else right = right.insert(x);// go right
return this;//root vertex has not changed
}//end insert
public vertex<T> search(T x)
{
int r = x.compareTo(head);
if(r==0)//go left
{
return left.search(x);//recursively call search using said node to move down tree
}
else //go right
{
return right.search(x);
}
}// end binary search
public void inorder()
{
Node<T> current_root = this;
if(current_root == null)
return;
left.inorder();
System.out.println(current_root + ", ");
right.inorder();
}//end inorder print
/*public Node<T> Attack_of_the_clones()
{
left_copy = curr_node.left.copy();
right_copy = curr_node.right.copy();
return new vertex(curr_node, left1, right1);
}*/
public vertex<T> largest(Node<T> x)
{
int left1 = largest(x.left);
int right1 = right.largest();
if(this.head > left1 && this.head > right1)
return this.root;
else
return Math.max(left1,right1);
}
}// end vertex
public class BinaryTree
{
public static void main(String[] args)
{
Node<Integer> n = new vertex<Integer>(3);
n = n.insert(4);
for(int i = 0; i < 10; i++)
{
n.insert((int)Math.random*8);
}
n.size();
n.depth();
n.inorder();
}//end main
}//end Binary Tree
BinaryTree.java:87: warning: [rawtypes] found raw type: vertex
public Node<T> Attack_of_the_clones() { return new vertex(head, left.Attack_of_the_clones(), right.Attack_of_the_clones());}
^
missing type arguments for generic class vertex<T>
where T is a type-variable:
T extends Comparable<T> declared in class vertex
BinaryTree.java:87: warning: [unchecked] unchecked call to vertex(T,Node<T>,Node<T>) as a member of the raw type vertex
public Node<T> Attack_of_the_clones() { return new vertex(head, left.Attack_of_the_clones(), right.Attack_of_the_clones());}
^
where T is a type-variable:
T extends Comparable<T> declared in class vertex
BinaryTree.java:87: warning: [unchecked] unchecked conversion
public Node<T> Attack_of_the_clones() { return new vertex(head, left.Attack_of_the_clones(), right.Attack_of_the_clones());}
^
required: Node<T>
found: vertex
where T is a type-variable:
T extends Comparable<T> declared in class vertex
3 warnings
As Nil has no fields (is immutable) then its clone can just return itself.
//On Nil
public Node<T> myClone(){
return this;
}
On Vertex you want to do a deep clone (cloning the fields instead of just copying their references).
//On Vertex
public Node<T> myClone(){
return new Vertex<T>(head,left.myClone(),right.myClone())
}