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())
}
Related
My goal is to create a tree-like object structure.
For this i created a class named Node (I removed the implementation because the problem still persists without it):
public class Node<S> {
public Node<S> addChild(Node<S> node) {
return this;
}
}
Important to know is that i want to define the generic type S only in the root node, all child nodes should automatically inherit from the root node.
Something like this:
new Node<String>().addChild(
new Node<>().addChild(
new Node<>()
)
)
I restricted the addChild method to only accept Nodes with the same generic type S,
so as far as i know my child node should know that it's generic type S has to be (in this example) String. However it seems like the generic type S gets lost after instantiating a new Node, because it gives me the following Exception:
error: incompatible types: Node<Object> cannot be converted to Node<String>
The use of <> requires type inference, and the argument of the first
addChild must be a Node, and just passing new Node<>() would do - infering from the return type.
But chaining to .addChild(new Node<>()) cannot infer anything, can only provide Node<Object>. So: one cannot use <>.
The problem is (of course) that you want addChild to return the head of the list, and keep adding to the tail of the list.
Normal practice is not to create Node instances, but just use the S values.
public class Node<S> {
private S value;
private Node<S> next;
public Node(S value) {
this.value = value;
}
public static <T> void print(Node<T> root) {
if (root == null) {
System.out.println("empty");
return;
}
System.out.print(root.value);
System.out.print(" --> ");
print(root.next);
}
public static <T> Node<T> addAll(T... values) {
Node<T> root = null;
Node<T> previous = null;
for (T value : values) {
Node<T> current = new Node<>(value);
if (root == null) {
root = current;
} else {
previous.next = current;
}
previous = current;
}
return root;
}
public static void main(String[] args) {
Node<String> root = Node.addAll("a", "b", "c", "d");
print(root);
}
}
Comparable to Collections.addAll or List.of. If you keep a Node<S> last field, you could indeed create something like:
public void addLast(S value) {
last.next = new Node<>(value);
}
This also shows a serious problem of the class: an empty list is not a Node.
One could use Optional<Node<S>> or a special constant for an empty list EMPTY - without value.
The normal solution is to have a container:
public class List<S> {
private class Node {
...
}
private Node<S> root;
private Node<S> last;
private int size;
public List<S> addLast(S value) {
Node<S> current = new Node<>(value);
if (root == null) {
root = current;
last = current;
} else {
last.next = current;
}
last = current;
++size;
return this;
}
private int size() {
return size;
}
...
}
Now everything fits.
List<String> nodes = new List<>()
.addLast("a")
.addLast("b")
.addLast("c")
.addLast("d");
After feedback, when wanting Node references.
Then discard chaining, and make Node public again.
public Node<S> addLast() {
addLast(null);
}
public Node<S> addLast(S value) {
Node<S> current = new Node<>(value);
if (root == null) {
root = current;
last = current;
} else {
last.next = current;
}
last = current;
++size;
return last;
}
List<String> nodes = new List<>()
Node<String> a = nodes.addLast();
Node<String> b = nodes.addLast();
var c = nodes.addLast();
var d = nodes.addLast();
One could use var for shortness.
What you are trying to do is something like this
public class Node<T> {
private Node<T> child;
private T data = null;
public Node (T data) {
this.data = data;
}
public T getData() {
return data;
}
public Node<T> getChild() {
return child;
}
public void addChild(Node<T> child) {
this.child = child;
}
#Override
public String toString() {
return "this node's data: " + data + "; has child? " + (child != null);
}
public static void main(String[] args) {
Node<String> root = new Node<> ("parent");
Node<String> child = new Node<>("child");
root.addChild(child);
System.out.println(root);
System.out.println(child);
}
}
If you were to execute this, it will output
this node's data: parent; has child? true
this node's data: child; has child? false
this node's data: 0; has child? false
this node's data: 1; has child? false
Notice how I can create nodes of type String and Integer. However, this class is incomplete if you want to create a tree structure. The implementation of "tree" will depend on what kind of tree you are talking about. For example, a simple binary tree will have two children at most. Other types of trees could have more children. Also, adding nodes to a tree might require balancing the tree.
Now, to your question, this answer suffices. I was able to demonstrate the use of generics to create Node objects of type T.
My toString() method at the bottom is giving me the above error when trying to test for an empty DoublyLinkedList in my main method also at the bottom. My intuition tells me that this may be caused by the List interface that I'm implementing since the word "List" is underlined in red reading "The type List is already defined" and the isEmpty() method is pulled from that interface. Not entirely sure though. Hope this isn't a burden to anyone. Thanks in advance.
public class DoublyLinkedList<T> implements List<T> {
/**
* Node is a pair containing a data field and a pointers to
* the previous and next nodes in the list.
*/
class Node {
T data;
Node next, prev;
Node(T data) {
this(data, null, null);
}
Node(T data, Node prev, Node next) {
this.data = data;
this.prev = prev;
this.next = next;
}
}
Node head; // always points to the headnode for this list
int n; // the number of nodes in this list, initially 0
/**
* Creates the empty list.
*/
public DoublyLinkedList() {
// TODO: Create the headnode.
// Note that the prev and next fields in the headnode should
// point back to the headnode.
Node head = new Node(null);
head.prev=head;
head.next=head;
}
public String toString() {
System.out.println("meeee");
if (this.isEmpty())
return "()";
Iterator<T> it = iterator();
StringBuilder ans = new StringBuilder("(").append(it.next());
while (it.hasNext())
ans.append(" ").append(it.next());
return ans.append(")").toString();
}
public static void main(String... args) {
DoublyLinkedList<Integer> xs = new DoublyLinkedList<>();
System.out.println(xs.toString());
}
interface List<T> extends Iterable<T> {
void add(T x); // simple add
T remove(int i);
T get(int i);
boolean contains(T x);
int size();
default boolean isEmpty() {
return size() == 0;
}
}
Is there a way to use the compareTo function when comparing objects, I'm not sure if it's just for Strings. I am trying add an node into its correct position in ascending order.
heres where I declare my attributes/constructor
private Node<E> head; //refers to the head of the node
private int size; // keeps track of the size of the list
// default constructor which creates empty ordered list
public OrderedList(){head = null; size = 0;}
Heres my insert function
public void insert(Object o)
{
Node n = new Node(o, null); // creates new node
// Node for first element greater than or equal
Node current = head.getLink();
Node before = head; // Node for right before the next one is found
// checks to see if list is empty
if(size == 0)
{
head = n;
}
// checks if element is smaller than the head
else if (o.compareTo(head.o) < 0)
{
n.getLink() = head;
head = n;
}
}
here is my node class
package project.pkg3;
public class Node<T>
{
private Object data;
private Node link;
public Node(Object o, Node l){data = o; link = l;}
public void setData(Object o){data = o;}
public void setLink(Node l){link = l;}
public Object getData(){return data;}
public Node getLink(){return link;}
}
I'm getting an error message when trying to check whether the element belongs in the front on this line
else if (o.compareTo(head.o) < 0)
telling me that it cannot find the symbol, which I'm not sure what that means
Im also getting another error message on this line
n.getLink() = head;
this one is telling me that it's an unexpected type
If your linked list must be sorted using compareTo(), then you need to make sure that the underlying data is comparable.
public class Node<T extends Comparable>
{
private T data;
private Node<T> link;
public Node(T o, Node<T> l) { data = o; link = l; }
public void setData(T o) { data = o; }
public void setLink(Node<T> l) {link = l; }
public T getData() { return data; }
public Node<T> getLink() { return link; }
}
Then this block
else if (o.compareTo(head.o) < 0)
{
n.getLink() = head;
head = n;
}
should be changed into this:
else if (
(o.getData() != null) ?
(o.getData().compareTo(head.getData()) < 0) :
(head.getData().compareTo(o.getData()) > 0)
)
{
n.setLink(head);
head = n;
}
I didn't look at your linked list implementation though, so I have no idea the other stuff are correct.
Your node class should implement java.lang.Comparable interface and override its compareTo() method as per your logic.
public class Node<T extends Comparable<T>>{
}
Your argument object would implement Comparable interface. For eg:
public class Name implements Comparable<Name> {
private String str1;
public int compareTo(Name o) {
//your logic here to compare object with itself
return this.str1.compareTo(o.str1);
}
}
I'm trying to create a SortedList class that extends a LinkedList class, only difference between the two is the SortedList has a method to insert whatever its holding in order.
public class SortedList<T> extends LinkedList<T> implements Iterable<T> {
// Class variables and constructor
public void insert(T objectToAdd){
Node<T> newNode = new Node<>(objectToAdd);
Node<T> currentNode = head.getNext(); // Head node is a single sentinel node, so we always need to start comparing from its next.
if (objectToAdd.compareTo(currentNode.getPayload()) == -1){
// Insert and setup node links.
} else if (... rest of here){
}
}
Problem I'm having is using the compareTo gives this error:
http://puu.sh/vxKxv/c9ee91d54c.png
Here is the Node class.
public class Node<T>{
// Class Variables
private final T data;
public int index;
private Node<T> next;
private Node<T> prev;
public Node(T data) {
this.payload = payload;
this.next = null;
this.prev = null;
}
public void setNext(Node<T> newNode) {
this.next = newNode;
}
public void setPrev(Node<T> newNode) {
this.prev = newNode;
}
public Node<T> getNext() {
return this.next;
}
public Node<T> getPrev() {
return this.prev;
}
public T getData() {
return this.data;
}
}
If you need me to post any of the other classes let me know.
Been stuck on this for awhile now, anyone able to help?
T is not a concrete type, hence compiler knows only that it has objects defined in Object class. If somebody makes the SortedList it will not have compareTo method, hence it cannot work. You need to make sure that T will contain the compareTo method. The easiest way is
public class SortedList<T extends Comparable> extends LinkedList<T> implements Iterable<T> { ... }
Also in my opinion it is better to check
if (objectToAdd.compareTo(currentNode.getPayload()) < 0) { ... }
because it gives you the relation that objectToAdd < currentNode.getPayload() visually. Also Comparable interface gives no guarantee it will be -1. It says:
#return a negative integer, zero, or a positive integer as this object
is less than, equal to, or greater than the specified object.
these are my fields:
public class BSTSet <E> extends AbstractSet <E> {
// Data fields
private BSTNode root;
private int count = 0;
private Comparator<E> comp; // default comparator
/** Private class for the nodes.
* Has public fields so methods in BSTSet can access fields directly.
*/
private class BSTNode {
// Data fields
public E value;
public BSTNode left = null;
public BSTNode right = null;
// Constructor
public BSTNode(E v) {
value = v;
}
//creates a method called contains so that i can call it later on for my find method
public boolean contains(Object item) {
return contains(item);//root.value.equals(item);
}
public int height() {
return height();
}
}
// Constructors - can either use a default comparator or provide one
public BSTSet() {
comp = new ComparableComparator(); // Declared below
}
public BSTSet(Comparator <E> c) {
comp = c;
}
}
and this is what i am trying to complete:
private class BSTSetIterator implements Iterator<E> {
private Stack<BSTNode> stack = new Stack<BSTNode>();
private BSTNode current = root;
public BSTSetIterator(BSTNode root) {
return new BSTSetIterator();
}
public boolean hasNext() {
boolean hasNext = false;
hasNext = !stack.isEmpty() || current != null;
return hasNext;
}
public E next() {
BSTNode next = null;
while (current != null) {
stack.push(current);
current = current.left;
}
next = stack.pop();
current = next.right;
return next;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
// Comparator for comparable
private class ComparableComparator implements Comparator<E> {
public int compare(E ob1, E ob2) {
return ((Comparable)ob1).compareTo(ob2);
}
}
So far the code fails at lines return new BSTSetIterator(); and return next;. For return next it says that it is the wrong data type to return. How would I go about fixing these methods so that I can iterate through a BST using a Stack?
BSTSetIterator();
This doesn't work, because your constructor expects a root and you didn't pass that parameter. If you have a BSTSet object called 'tree', and you want to create a new iterator, then you should create the iterator this way:
BSTSetIterator iterator = new BSTSetIterator(tree.getRoot());
However, you don't have a getter in your BSTSet class and your root is private. Don't worry, the solution for that problem is to create a public getter inside your BSTSetIterator class, like this:
public BSTNode getRoot()
{
return this.root;
}
Constructors don't return values, this is incorrect:
public BSTSetIterator(BSTNode root) {
return new BSTSetIterator();
}
Instead, write your construtor this way:
public BSTSetIterator(BSTNode root)
{
this.current = root;
}
Also, this definition is incorrect, because root is out of reach:
private BSTNode current = root;
You should have this instead:
private BSTNode current;
As for your other problem,
BSTNode next = null;
means that your variable called 'next' is of BSTNode type.
public E next()
means that your method called next is of E type. as E and BSTNode is not the same, your return:
return next;
is incorrect. I could give you more help, but I have realized you are learning now the language and it's better to let you explore yourself the technology and programming in general, because this way you will become quicker. "Give a man a fish, and you feed him for a day. Teach a man how to fish, and you feed him for a lifetime."