I want to create a tree that detect if the insert is a Object of type Characters it will compare each one and decide where to insert [ right or left ],( i know it can detect by position in ascii table) ,and if the insert is an object of int it will do the same operation.
My Questions:
1. I need to create the tree and on the same time to set a compartor ( for example if its a tree of Chars it will be a Chars_comperator that checks Chars and he implements Comparator ( of java ).?
2. My code now is good for int only. becuase i take the object convert to string and then to int and after all this i compare and decide where to insert, this is how i need to do it? or there is another way to do it that can take care all of kinds of Objects?
Here is my code and how i create the tree,
Tree class
public class tree {
bNode root;
public tree() {
this.root = null;
}
public boolean isEmpty(){
return root==null;
}
public void insert(Object data)
{
if(isEmpty())
this.root = new bNode(data);
else
this.root.insert(data);
}
}
bNode Class
public class bNode {
protected Object data;
protected bNode left;
protected bNode right;
public bNode(Object data) {
this.data = data;
this.left = null;
this.right = null;
}
public void insert(Object data){
if(Integer.parseInt(data.toString())<Integer.parseInt(this.data.toString())){
if(this.left==null)
this.left = new bNode(data);
else
this.left.insert(data);
}
else{
if(this.right==null)
this.right = new bNode(data);
else
this.right.insert(data);
}
}
Main class
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
tree x = new tree();
char a = 'G';
x.insert(a);
x.insert(60);
x.insert(40);
x.insert(30);
x.insert(59);
x.insert(61);
x.root.printTree(x.root);
}
}
Thanks!
instead of passing an Object, you could pass a Comparable in insert().
Standard type like Integer, String, etc. already implement the Conparable interface.
instead of using if (a <b) you call
compareTo(a,b);
See java doc of Comparable.
If, for any reason, you want to stay with Passing an Object to insert(), you also can solve that by not using toString, but by checking the class of object, and then casting:
if (object instanceof Integer) {
int val = ((Integer) object).intValue();
// now compare
} else if (object instance of String) {
String val .....
// use val.compareTo()
}
Related
In this binary tree implementation
I've tried to create an object from the BinaryTree class and thus insert elements and access them in order. While debugging it seems it's always returning root as NULL and thus the traversal fails.
I don't understand what I'm missing here. Where is my mistake?
public class BinaryTree{
public static class Node{
int value;
Node left;
Node right;
public Node(int data){
this.value = data;
left = null;
right = null;
}
}
Node root;
BinaryTree() {
root = null;
}
public Node addrecursive(Node current,int value){
if(current==null){
return new Node(value);
}else
if(value<current.value){
int n=current.value;
current.left=addrecursive(current.left,value);
}else
if(value>current.value){
int n=current.value;
current.right=addrecursive(current.right,value);
}else
{
return current;
}
return current;
}
public void add(int value) {
Node n = null;
if(root==null)
root = addrecursive(root, value);
else
n = addrecursive(n, value);
}
private void createBinaryTree(){
BinaryTree bt = new BinaryTree();
bt.add(6);
bt.add(4);
bt.add(8);
bt.add(3);
bt.add(5);
bt.add(7);
bt.add(9);
return;
}
private boolean containsNodeRecursive(Node current, int value) {
if (current == null) {
return false;
}
if (value == current.value) {
return true;
}
return value < current.value
? containsNodeRecursive(current.left, value)
: containsNodeRecursive(current.right, value);
}
public boolean containsNode(int value) {
return containsNodeRecursive(this.root, value);
}
public void traverseInOrder(Node node) {
if (node != null) {
traverseInOrder(node.left);
System.out.print(" " + node.value);
traverseInOrder(node.right);
}
}
void printInorder() { //wrapper class for access without passing node
traverseInOrder(root);
}
public static void main(String [] args){
BinaryTree bt = new BinaryTree() ; //object of class
bt.createBinaryTree(); //creating the binary tree within that object
Boolean b = bt.containsNode(7);
System.out.println(b);
System.out.println("\nInorder traversal of binary tree is " );
bt.printInorder();
}
}
There are several issues:
In addrecursive the variable n is a local reference that is unrelated to your root. So whatever n = addrecursive(n, value); does with the null that you pass as argument, it doesn't do anything with the linked list that starts at root.
It is actually quite simple... Your addrecursive function should only do:
public void add(int value) {
root = addrecursive(root, value);
}
The assignment to root is only really needed when root was null, but it doesn't hurt to always make that assignment. It is however important to pass root as argument, as that is the lead for where to append the new node.
createBinaryTree creates a new local instance of BinaryTree (which is already strange, since this already is an instance), adds nodes to it, and then just discards that local instance -- all work done for nothing. There are different ways to solves this, but I would make this method a static method, and have it return the BinaryTree instance that it populated. The caller in main should then take that returned tree and assign it to its own variable:
// Static!
private static BinaryTree createBinaryTree(){
BinaryTree bt = new BinaryTree();
bt.add(6);
bt.add(4);
bt.add(8);
bt.add(3);
bt.add(5);
bt.add(7);
bt.add(9);
return bt; // return the work that was done
}
public static void main(String [] args){
// Call static function to get the reference to the new tree
BinaryTree bt = createBinaryTree();
Boolean b = bt.containsNode(7);
System.out.println(b);
System.out.println("\nInorder traversal of binary tree is " );
bt.printInorder();
}
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.
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 created a class to simulate a stack. Right now the type is fixed to float. I'v seen in java util class they have a stack class ware you can define the type.
I could not find anything on how to creat a class where a type for one of its verbols can be define when the object is created. I tried googling java template totiol, I think in c they called this templates.
so I have the classpublic class cStack {
float data[];
int size=0;
int pes=0;
cStack(int size)
{
data=new float[size];
pes=0;
}
now data is def as a float, I would like it so when I create the class I can set the type. So it can hold floats, or integers or strings.
This is generic LinkedStack implementation from Bruce Eckel's "Thinking in Java":
public class LinkedStack<T> {
private static class Node<U> {
U item;
Node<U> next;
Node() {
item = null;
next = null;
}
Node(U item, Node<U> next) {
this.item = item;
this.next = next;
}
boolean end() {
return item == null && next == null;
}
}
private Node<T> top = new Node<T>(); // End sentinel
public void push(T item) {
top = new Node<T>(item, top);
}
public T pop() {
T result = top.item;
if (!top.end())
top = top.next;
return result;
}
public static void main(String[] args) {
LinkedStack<String> lss = new LinkedStack<String>();
for (String s : "Phasers on stun!".split(" "))
lss.push(s);
String s;
while ((s = lss.pop()) != null)
System.out.println(s);
}
}
I'll recommend you to read the whole book and especially the "Generics" chapter.
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."