Implementing comparable for Tree class - java

My assignment deals with Huffman encoding and I am using a priority queue of trees to create it. I am trying to implement comparable for my Tree class and then have a compare To method so that the Trees can be sorted in the priority queue by frequency. I am getting some error messages when trying to do this and I am not sure why.
n00832607.java:249: error: Tree is not abstract and does not override abstract method
compareTo(Object) in Comparable
class Tree implements Comparable
^
n00832607.java:423: error: method does not override or implement a method from a supertype
#Override
^
Here is the code that is giving me trouble.
//Begin tree class
class Tree implements Comparable
{
private Node root; // first node of tree
// -------------------------------------------------------------
public Tree(char data, int frequency) // constructor
{
root = new Node();
root.iData = frequency;
root.dData = data;
}
public Tree(Tree leftChild, Tree rightChild)
{
root = new Node();
root.leftChild = leftChild.root;
root.rightChild = rightChild.root;
root.iData = leftChild.root.iData + rightChild.root.iData;
}
protected Tree(Node root)
{
this.root = root;
}
//end constructors
//Misc tree methods inbetween the constructors and compareTo, I can post them if that would help
#Override
public int compareTo(Tree arg0)
{
Integer freq1 = new Integer(this.root.iData);
Integer freq2 = new Integer(arg0.root.iData);
return freq1.compareTo(freq2);
}
} // end class Tree
////////////////////////////////////////////////////////////////
Also here is my Node class if that is of any help
//Begin node class
////////////////////////////////////////////////////////////////
class Node
{
public int iData; // data item (frequency/key)
public char dData; // data item (character)
public Node leftChild; // this node's left child
public Node rightChild; // this node's right child
public void displayNode() // display ourself
{
System.out.print('{');
System.out.print(iData);
System.out.print(", ");
System.out.print(dData);
System.out.print("} ");
}
} // end class Node
////////////////////////////////////////////////////////////////

You're using the raw Comparable type, instead of using the generic Comparable<Tree> type. To compile, as is, your compareTo() method should thus take an Object as argument, and not a Tree. But of course, the correct way to fix it is to make your class implement Comparable<Tree>.
Also, note that instead of creating two new Integer instances at each comparison, you could simply use (since Java 7):
return Integer.compare(this.root.iData, arg0.root.iData);

Related

Adding new layer of children in a Tree

I'm making a Tree and have been able to implement setting the Parent and child properly. I'm stuck at attempting to make a new layer of the tree, a grandchild in this case. It isn't a binary tree. Ideally I'd like to place the implementation of the new layer in either the constructor or in the addChild method. The following is what I have for my set up and the methods setting up my Parent and Children in my Tree
import java.util.ArrayList;
import java.util.List;
public abstract class TreeNode {
static int count; // store # tree nodes created. Generate IDs
private String id;// unique id # of nodes.
private List<TreeNode> children; // store all children of node
private TreeNode parent; // reference parent of the node. Null is node is root
public TreeNode(List<TreeNode> children) {
this.children = children;
this.count++;
this.id = Integer.toString(this.count);
int ctr = 0;
if (children != null) {
while (ctr < children.size()) {
children.get(ctr).setParent(this);
ctr++;
}
}
}
public void addChild(TreeNode child) { // add single child to current node
if (this.getChildren() == null) {
child.setParent(this);
this.setChildren(new ArrayList<TreeNode>());
this.children.add(child);
}
else {
child.setParent(this);
this.children.add(child);
}
}
Why is the class abstract? (I can't see an intent or a reason to extend it.)
Perhaps I don't understand what you're asking; from where I'm sitting, you already have support for "a new layer of the tree" -- as many as you want, in fact (at least of the class weren't abstract)...
TreeNode grandparent = new TreeNode(new ArrayList<TreeNode>()); // I recommend a zero-arg constructor that does this
TreeNode child = new TreeNode(new ArrayList<TreeNode>());
grandparent.addChild(child);
TreeNode grandchild = new TreeNode(new ArrayList<TreeNode>());
child.addChild(grandchild);
You now have a 3-level tree.
More Suggestions
Your id field
What is the purpose of the id filed? As you have it, you could get duplicates in a multi-threaded context. Better would be...
this.id = UUID.randomUUID().toString();
Every TreeNode would receive a unique id for certain (though they wouldn't be numeric or sequential).
Also, id values based on UUID will be unique even if you restart your VM and you're using persistent TreeNode objects.
The loop in your constructor
Better than...
while (ctr < children.size()) {
children.get(ctr).setParent(this);
ctr++;
}
would be...
for (TreeNode child : children) {
child.setParent(this);
}

How to properly implement in-between model of ListIterator?

I'm trying to write my own CustomLinkedList<E> to rapidly pass labs where I need to implement stacks and queues. I can pass the labs without this class (since I don't need to implement iterable at all), but I would like to grasp the concept since I'm learning java anyway.
I've got most of things running and tested now, but I couldn't make iterator to work properly yet.
The first approach was "post-increment", e.g.:
E result = current.getValue();
current = current.getNext();
return result;
which I found to be broken, because then when I reach the end of the list, I won't be able to get back. My hasNext() just checks if the current is null, thus the ability to go back is lost.
The second approach was to add dummy Node on creation, to model the beginning. It had an issue of determining if I'm at the beginning of the list, since with this approach I don't know where is the beginning until its too late.
Iterator(Node root)
{
current = new Node(null, null, root);
}
public E next()
{
//checks and stuff
current = current.getNext();
return current.getValue();
}
So, question is: is it possible to implement ListIterator<> only knowing the current element? If yes, some code scratches would be great.
EDIT:
Node:
private class Node
{
private Node prev;
private T value;
private Node next;
Node(Node prev, T value, Node next) {
this.setPrev(prev);
this.setValue(value);
this.setNext(next);
}
//getters and setters
}
CustomLinkedList<E>:
public class CustomLinkedList<T> implements Iterable<T>{
private class Node {/**/}
private class Iterator implements java.util.ListIterator<T> {
Node current;
public Iterator(Node root) //from the first approach
{
current = root;
}
//other methods
}
Node root;
int size;
//Object methods, and some basic Collection methods
}
I would do something like this:
public class CustomLinkedList<T> implements Iterable<T>{
private class Node {/**/}
private class Iterator implements ListIterator<T> {
Node next, previous;
Iterator() {
next = root;
previous = null;
}
public boolean hasNext() {
return next != null;
}
public T next() {
if ( ! hasNext()){
throw new NoSuchElementException();
}
previous = next;
next = next.getNext();
return previous;
}
public boolean hasPrevious() {
return previous != null;
}
public T previous() {
if ( ! hasPrevious() ){
throw new NoSuchElementException();
}
next = next.getPrevious();
previous = next.getPrevious();
return next;
}
}
Node root;
int size;
//Object methods, and some basic Collection methods
}
This doesn't implement the other methods of the ListIterator interface, but you get the idea. You need to think of your iterator's cursor as being in-between the previous and the next element, not on one of them. For a proper implementation, see Jorn Vernee's link.

How to add a child to a specific node in n-array tree?

I wrote this n-array tree class. I want to write a method to add a child to a specific node in my tree.
First I should search my tree to find the father then add the child to that node children.
I don't know how I should declare my method
public class FamilyNode {
public String name;
public String Family;
public String sex;
public FamilyNode Father;
public FamilyNode Mother;
public FamilyNode Spouse=null;
public String status="alive";
public int population;
public ArrayList<FamilyNode> children=new ArrayList<FamilyNode>() ;
public FamilyNode(String firstname,String lastname,String sex1){
this.name=firstname;
this.Family=lastname;
this.sex=sex1;
this.population=this.children.size()+1;
}
public void SetParents(FamilyNode father,FamilyNode mother){
this.Father=father;
this.Mother=mother;
}
public void SetHW(FamilyNode HW){
this.Spouse=HW;
}
public int Number (){
int number_of_descendants = this.population;
if(this.Spouse!=null) number_of_descendants++;
for(int index = 0; index < this.children.size(); index++)
number_of_descendants = number_of_descendants+ this.children.get(index).Number();
return number_of_descendants;
}
public void AddChild(FamilyNode Father,FamilyNode child){
//the code here
}
}
I answered one of your related questions yesterday so let's continue with the code I posted :)
public class FamilyNode {
// ...
// ...
public FamilyNode findNodeByName(String nodeName){
if(name.equals(nodeName)){
// We found a node named nodeName, return it
return this;
}
// That's not me that you are looking for, let's see my kids
for(FamilyNode child : children){
if(child.findNodeByName(nodeName) != null)
// We found what we are looking, just return from here
return child;
}
// Finished looping over all nodes and did not find any, return null
return null;
}
public void addChild(FamilyNode child){
children.add(child);
}
}
Basically, you need to find the node you are looking for (by name in this case) and that can be done by the findNodeByName above. Once the node is found, add one child to it.
Use this code like this:
FamilyNode root = ...;
FamilyNode node = root.findNodeByName("Parent");
if(node != null) node.addChild(...);
NOTE
If you want to debug and visit all your tree nodes, use this method:
public FamilyNode findNodeByName(String nodeName){
System.out.println("Visiting node "+ name);
// That's not me that you are looking for, let's see my kids
for(FamilyNode child : children){
child.findNodeByName(nodeName)
}
// Finished looping over all nodes and did not find any, return null
return null;
}
This isn't exactly a tree, as children have potentially two parents rather than just one. It's a directed graph.
It would be good to change your variable and method names to be consistent with the usual Java convention of starting with a lowercase character.
In the interest of data consistency, you might consider making the addChild method something that simply adds to the list of children for the current node, but in your setParents method, update the child lists of both parents, adding the current node as a child there, by calling father.addChild(this) and mother.addChild(this) (protecting against them being null of course).
If the parents can be changed when they're previously set (presumably in error), you'll also need to remove the current node from previously set parents. For this, you might need a removeChild(FamilyNode child) method. Again for data consistency, this method should probably also set the appropriate parent field in the child node to null.

ID3 Java Enum Tree

I'm trying to make a non-binary learning tree that's a simplified version of the ID3 algorithm. To do this, I tried to use enums, because there are several references teaching enum hierarchies, but I'm having trouble with the transfer of enums to the functions I need to make the tree. I've set up everything I need for the tree as best as I could, but I'm having trouble with the initial construction of the tree.
First, I made six enums, each with their own file so I wouldn't need to write "main.enumname" everywhere. These first five enums represent car diagnostics.
public enum fuelstats {notempty, empty}
public enum lightstatus {Dim, Normal}
public enum scents {normal, gas}
public enum soundstatus {Normal, Howl, Screech, Click}
public enum turn {no, yes}
Next, I made two more enums. One for the different diagnostic results, and one for the different "topics" of car diagnostics.
public enum problems {battery, starter, solenoid, outofgas, flooding}
public enum features {lightstatus, soundstatus, fuelstats, scents, turn, problems}
I then made five data examples of different car diagnostics to be sorted in the tree.
Example example1 = new Example(lightstatus.Dim, soundstatus.Howl, turn.yes, fuelstats.notempty, scents.normal, problems.battery);
Example example2 = new Example(lightstatus.Normal, soundstatus.Screech, turn.no, fuelstats.notempty, scents.normal, problems.starter);
Example example3 = new Example(lightstatus.Normal, soundstatus.Click, turn.no, fuelstats.notempty, scents.normal, problems.solenoid);
Example example4 = new Example(lightstatus.Normal, soundstatus.Normal, turn.yes, fuelstats.empty, scents.normal, problems.outofgas);
Example example5 = new Example(lightstatus.Normal, soundstatus.Normal, turn.yes, fuelstats.notempty, scents.gas, problems.flooding);
//make an array list of Examples.
ArrayList<Example> Examples = new ArrayList<Example>();
Examples.add(example1);
Examples.add(example2);
Examples.add(example3);
Examples.add(example4);
Examples.add(example5);
I put the various car diagnostics, called Features, in an ArrayList for shuffling purposes, because they will be randomly used to build the tree.
//This ArrayList holds the Enums for shuffling purposes.
ArrayList<features> Features = new ArrayList<features>();
Features.add(features.soundstatus);
Features.add(features.lightstatus);
Features.add(features.turn);
Features.add(features.scents);
Features.add(features.fuelstats);
// Shuffle the elements in the list
Collections.shuffle(Features);
//The Features Array List is now a shuffled tree.
//We will do a single loop that will serve as our stack.
//First we take the top of the list and assign it to the root.
Tree id3 = new Tree(Features.get(0),Examples);
But how do I write a tree that:
Takes in a feature enum that makes the subject of the root match the enum, and all of the different statuses of the enum the children? For example, if soundstatus is the root, it should make four children that are Normal, Howl, Screech, and Click. That way I can match the Example sounds with the children sounds. This is my node so far.
public class Node
{
ArrayList<Node> children;
/* Constructor*/
public Node(ArrayList<Node> ExampleList)
{
this.ExampleList = ExampleList;
this.parent = parent;
this.children = children;
}
public ArrayList<Node> getChildren()
{
return children;
}
public void addChild(Node n)
{
children.add(n);
}
private ArrayList<Node> children;
Enum phrase;
private boolean isUsed;
Node parent;
public void setUsed(boolean isUsed)
{
this.isUsed = isUsed;
}
public boolean isUsed()
{
return isUsed;
}
//This method states if the node is a leaf
public boolean isLeaf()
{
if (this.getChildren() == null)
return true;
else
return false;
}
}
you can add a child class to features:
import java.util.*;
interface hasEnumChildren {
Class clazz();
}
enum fuelstats {
notempty,empty
}
enum lightstatus {
Dim,Normal
}
enum scents {
normal,gas
}
enum soundstatus {
Normal,Howl,Screech,Click
}
enum turn {
no,yes
}
enum problems {
battery,starter,solenoid,outofgas,flooding
}
enum features implements hasEnumChildren {
lightstatus(lightstatus.class),soundstatus(soundstatus.class),fuelstats(fuelstats.class),scents(scents.class),turn(turn.class),problems(problems.class);
features(Class clazz) {
this.clazz=clazz;
}
final Class clazz;
#Override public Class clazz() {
return clazz;
}
}
public class So10233099 {
public static void main(String[] args) {
System.out.println(Arrays.asList(features.lightstatus.clazz().getEnumConstants()));
}
}
I had a similar problem, building an hierarchy of enums. But in my case, an hierarchy of classes could also do the trick. In case you are interested here is a question I posted:
How to build an hierarchy tree of categories in java using enums or any other way?
Now, concerning only enum hierarchy, as you can see above, I found that this may work for you:
http://alexradzin.blogspot.hk/2010/10/hierarchical-structures-with-java-enums_05.html
In particular:
public enum OsType {
OS(null),
Windows(OS),
WindowsNT(Windows),
WindowsNTWorkstation(WindowsNT),
WindowsNTServer(WindowsNT),
Windows2000(Windows),
Windows2000Server(Windows2000),
Windows2000Workstation(Windows2000),
WindowsXp(Windows),
WindowsVista(Windows),
Windows7(Windows),
Windows95(Windows),
Windows98(Windows),
Unix(OS) {
#Override
public boolean supportsXWindows() {
return true;
}
},
Linux(Unix),
AIX(Unix),
HpUx(Unix),
SunOs(Unix),
;
private OsType parent = null;
private OsType(OsType parent) {
this.parent = parent;
}
I hope it helps!

Guava Supplier : transforming a collection with each element's own function

Let's say I have a Node class that has a Function as an instance variable.
public class Node {
private Function<Node, Double> function;
...
I have a List of these Nodes:
List<Node> nodes = Lists.newLinkedList();
nodes.add(new Node(someFunction));
nodes.add(new Node(someOtherFunction));
I can do this:
public Collection<Double> getValues() {
SomeFunction f = new SomeFunction();
return Collections2.transform(nodes, f);
}
Sure enough, transform iterates over the nodes List and applies the function f to each element like mapcar.
What I'm trying to do is to have transform use the function that each node element has.
So I though that the Supplier would help.
class NodeSupplier implements Supplier<Node> {
Iterator<Node> iterator;
NodeSupplier(Iterable p) {
iterator = Iterators.cycle(p);
}
#Override
public Node get() {
return iterator.next();
}
}
Then a Function to get a Node.
class SupplierGetter implements Function<Supplier<Node>, Node> {
#Override
public Node apply(Supplier<Node> from) {
return from.get();
}
}
Then compose them:
FunctionGetter fg = new FunctionGetter();
NodeSupplier sup = new NodeSupplier(this); // the this class is Iterable
Supplier<Function<Node, Double>> supplier = Suppliers.compose(fg, sup);
But then it gives me a type mismatch when I try to use it:
Collections2.transform(nodes, supplier);
it wants suppler.get() which is called once.
Collections2.transform(nodes, supplier.get());
Is there an easier way?
I saw mention of
Suppliers.supplierFunction()
but that seem s to not exist in verison r09.
I'm confused by what you're trying to do... Supplier doesn't seem useful here. Each Node has its own Function. You want to transform a collection of Nodes by applying each Node's Function to itself. So why not just give the Node class some method:
// may want a better name
public Double applyFunction() {
return function.apply(this);
}
Then you'd just transform using a Function like this:
public Double apply(Node node) {
return node.applyFunction();
}
Apart from the fact that I also have my doubts about what you are trying to do, the following should achieve what you are asking for:
class Node {
private Function<Node, Double> function;
private static Function<Node,Double> applyFunction = new Function<Node,Double>() {
#Override
public Double apply(final Node input) {
return input.function.apply(input);
}
};
public static Iterable<Double> transform(final Iterable<Node> nodes) {
return Iterables.transform(nodes, applyFunction);
}
}
There is a third way to do this without modifying the Node class, if we suppose that Node exposes its function through a public getter.
Using an anonymous class :
public Collection<Double> getValues() {
return Collections2.transform(nodes, new Function<Node, Double>() {
#Override public Double apply(Node node) {
return node.getFunction().apply(node);
}
});
}
Using the enum singleton pattern (which I prefer, since it's clearer) :
public Collection<Double> getValues() {
return Collections2.transform(nodes, ApplyNodeFunction.INSTANCE);
}
/**
* A {#link Function} that applies the {#link Node}'s own function on itself.
*/
private enum ApplyNodeFunction implements Function<Node, Double> {
INSTANCE;
#Override public Double apply(Node node) {
return node.getFunction().apply(node);
}
}
The key to my question was this phrase: "So I thought that the Supplier would help." The answer is that it doesn't. I was trying to find a use for it - outside of Map creation which seems to be its main use. There was that one Suppliers method I mentioned but it seems to be MIA. Perhaps this could be an RFI for tranform be overloaded to take an Iterable as the second parameter

Categories

Resources