2

I'm generating a Binary Tree with key - value nodes.

It works like this: example Binary Tree(those numbers are the keys)

The ordering is as followed: If you implement a new node you give a key and a value(not important) it will check if there is a node already if not it will create it as the first node. now it checks if the key is smaller then the key of the first node, if so it will put it as the left node if there isn't already one, if there is one it will iterate to that and check it again. Same for the bigger key/right node. If the key is equal to the key of the current node it will override the node.

This method is working if I use something like int. Now I want to do it as a generic so I want to add compareTo from the Comparable interface, because I could check if the key is smaller, equal or greater than the key of the current node. I know I have to use the keys but I can't code any compareTo method myself. I'm not sure how to get it to work.

@Override
public int compareTo(TreeNode<Type> node) {
    //method
}

Attributes I'm currently using in my program are: Nodes(first,previous,left,right), key, value Type key, value Node myNodes(previous,...)

classdefinitions:

public class Tree<Type> {
    ...
    public class TreeNode<Type extends Comparable<Type>>{
        ...
    }
    public int compareTo(TreeNode<Type> Node){
        //method
    }
}
NhatNienne
  • 937
  • 3
  • 11
  • 20
  • Basically, you do not have to implement compareTo as the Comparable interface is already implemented for Numeric and String types in Java and you can write any other implementation for any other **specific** custom class. In the tree, you have just to use it. But, try to be clearer as I cannot understand last part of your question. – Nicola Ferraro Jan 09 '15 at 23:10
  • so firstly I don't know which Types gonna be used that depends on my teacher.. So I have to get a generic version of compareTo which is comparing generic keys of two nodes somehow and checking which one is "smaller" or "greater". the last part is just to show how each attribute is defined – NhatNienne Jan 09 '15 at 23:13

2 Answers2

4

Right now what your code says is:

There is a tree of type type, which can be compared to other trees of type type.

What you seemingly want to say is:

There is a tree, built from elements of type type, which are comparable to their own type.

In that case, you should define tree like this:

public class Tree<T extends Comparable<T>> {
     private class TreeNode<F extends<Comparable<F>> implements Comparable<TreeNode<F>>{
           private F f;
           ...
           public F getF(){return this.f;}
           @Override
           public int compareTo(TreeNode<F> node){
               return this.f.compareTo(node.getF());
           }
     }
     //Use TreeNode<T> here
     ...
}

Short summary: you have a Tree of type T, which is a type that can be compared to other objects of type T. Elements in the tree are represented by TreeNode<T>, which can be compared to other TreeNode<T>. The comparison of a TreeNode<T> to a TreeNode<T> can be done by comparing the Elements stored inside the TreeNode. There is a reason, why I have deviated from your original design in the last point (by name at least). If you think of T as the stored item, it is easier to think about how to extend the tree to support an item of type TreeItem, which enables you to build an associative data-structure on top of the tree.

Edit (in direct response, since OP requested clarification):

OP's code was something like this at the time of answer:

public class Tree<T> implements Comparable<Tree<T>>{
    ...
    TreeNode<???>{...}

}

Think of the TreeNode having a fixed member int key; for a second. You want to build a Tree: So you need TreeNodes, which can be compared to each other (i.e. TreeNode implements Comparable<TreeNode>)to build a Tree. You implement compareTo with int-comparisons. You now have a non-generic Tree.

To be able to make Tree generic, you need a generic TreeNode. So you make TreeNode generic and replace the formerly fixed field int key; by F f;. Now you can no longer implement comparison based on int-comparisons, so TreeNode has to be comparable to other instances of TreeNode somehow. It would be cool, if we could delegate that to F's comparison function. To make sure that works, the type has to be TreeNode<F extends Comparable<F>>. Of course we still need the basic hypothesis of comparable TreeNodes to hold so you end up with

class TreeNode<F extends<Comparable<F>> implements Comparable<TreeNode<F>>.

You now have a generic TreeNode<F>, that can be compared to other instances of TreeNode<F>.

Now you can build a generic Tree<T> from these nodes, as long as T is something that can be compared to other Ts, so Tree<T extends Comparable<T>>. Since you don't want to shadow the type of the inner class you differentiate between T and F and instantiate TreeNode<T>s when you use them inside the tree's functions. The existence of F is not seen from the outside.

midor
  • 5,487
  • 2
  • 23
  • 52
  • 2
    No! @NhatNienne Please do not update the question after people start answering it. It means that existing answers make no sense; and makes it impossible for anyone to provide a subsequent answer, which may or may not be better than this one. Stack Overflow is intended to be a repository of questions and answers that will be useful to future users. If you change the question, it makes the question not match the answers, and makes question and the whole set of answers completely useless to anyone other than yourself. PLEASE UNDO YOUR EDIT! – Dawood ibn Kareem Jan 09 '15 at 23:56
  • edited my question back (if i remember it correctly). But @midor so if I understand your code correctly you are defining F f;(f would be defined in my constructor) as the Object String or whatever my Type is and generating it as my saved key which I want to check? so the compareTo is comparing the keys right now am I right? (Don't want to copy things if I don't understand them) – NhatNienne Jan 10 '15 at 09:52
1

One of the requirements for a binary tree is that the node values must be ordered, so you should make your generic type for TreeNode <T extends Comparable<T>> instead of just <T>. Then your compareTo method can just delegate to the node's compareTo.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • like (take the code of my question) return key.compareTo(node.key);? gonna be updating my question with my class definitions. – NhatNienne Jan 09 '15 at 23:14
  • @NhatNienne Exactly. Note that you'll want to do the same thing for `hashCode` and `equals`; you should always define those two with anything that's `Comparable`, since `equals` is logically equivalent to `compareTo == 0`. – chrylis -cautiouslyoptimistic- Jan 09 '15 at 23:19