简体   繁体   中英

implementing compareTo (Comparable<T>) for a Binary Tree(Generic)

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

It works like this: 示例二叉树(以数字为键)

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
    }
}

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 TreeNode s, which can be compared to each other (ie 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 TreeNode s 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 T s, 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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM