Java tree classes - java

I'm trying to make my own tree class but keep getting horribly confused. Basically I'm trying to make a weighted tree. I've made the following node class:
import java.util.*;
public class subdivNode {
private int nodevalue;
private int nodeID;
private List<subdivNode> childnodes;
public subdivNode(int value, int id){
nodevalue = value;
nodeID = id;
}
public int getValue(){
return nodevalue;
}
public int getId(){
return nodeID;
}
public void addChild(subdivNode child){
childnodes.add(child);
}
public int getNumChildren(){
return childnodes.size();
}
public subdivNode getChild(int pos){ //return's i'th child
return childnodes.get(pos);
}
}
And this is the skeleton for my tree class so far:
public class subdivTree {
private subdivNode rootnode;
public subdivTree(){
rootnode = new subdivNode(0,0);
}
public void addNode(int parent, int value){
}
public int getNodeValue(int node){
return 0;
}
public int getNumChildren(int node){
return 0;
}
}
Beyond that I have no idea
EDIT: Sorry for the ambiguity. My question should have been how would I go about implementing the addnode method in subdivTree. The end goal is to create an alogrithim which searches the tree for the path between any two nodes such that the greatest value(adding the value of all the in between nodes) is obtained.

Before working on addNode, tell us how getNodeValue(int node) is going to work.
You have a rootNode, what method of that are you going call with that "node" value?
I'm not sure, but I think that your interface is broken. I think your concepts of get by position and get by Id are confused.
Draw a picture of the data structure you expect.

Related

What is a good way to implement calculations for extended classes?

I have the following classes:
public class Node {
private int x;
private int y;
}
public abstract class Map {
protected Node[][] grid;
public abstract Set<Node> findNeighbours(Node node);
}
public class SquareMap extends Map {
private static final int VERTICAL_COST= 10;
private static final int HORIZONTAL_COST= 10;
private static final int DIAGONAL_COST = 14;
#Override
public Set<Node> findNeighbours(Node node) {
//return the 8 adjacent nodes
}
}
public class HexMap extends Map {
private static final int MOVE_COST = 10;
#Override
public Set<Node> findNeighbours(Node node) {
//return the 6 adjacent nodes
}
}
I would like to create a method like
public int calculateMoveCost(Node current, Node target, <whatever else is needed>) {}
Where I only pass in the nodes, and the logic in either the method, or the nodes, or the map recognizes what kind of map I'm using. My current solution looks like this:
private int calculateMoveCost(Node current, Node target, Map map) {
int cost;
if(isHexMap(map)) {
cost = map.getMoveCost();
} else {
if(isSquareMap(map)) {
if(verticalNeighbours(current, target)) {
cost = map.getVerticalMoveCost();
} else {
cost = map.getHorizontalMoveCost();
}
}
}
return cost;
}
When I look at this code, I think there has to be a better way to implement this. Could you recommend a nice object oriented way of implementing this? I can create any reference in any object, the goal is to have a nice solution. Thanks!
I do think there is a right answer for this, just have an abstract getMoveCost method on Map and implement it in each subclass. Then you can just call map.getMoveCost(from, to).
public abstract class Map {
protected Node[][] grid;
public abstract int getMoveCost(Node current, Node target);
public abstract Set<Node> findNeighbours(Node node);
}
public class SquareMap extends Map {
private static final int VERTICAL_COST= 10;
private static final int HORIZONTAL_COST= 10;
private static final int DIAGONAL_COST = 14;
#Override
public Set<Node> findNeighbours(Node node) {
//return the 8 adjacent nodes
}
#Override
public int getMoveCost(Node current, Node target) {
if(verticalNeighbours(current, target)) {
cost = getVerticalMoveCost();
} else {
cost = getHorizontalMoveCost();
}
}
}

Java, how to sort an list of Nodes by an objects field

I made an class called myLinkedList that stores nodes from a class called LinkNodes that takes an object with an name(String), as a field. I want to sort the nodes in my list alphabetical, from the memberPlayer field firstName
public class LinkNode {
public memberPlayer player;
public LinkNode next;
public LinkNode() {
this(null, null);
}
public LinkNode(memberPlayer player) {
this(player,null);
}
public LinkNode(memberPlayer player, LinkNode next) {
this.player = player;
this.next = next;
}
public String toString() {
String result = player + " ";
if (next != null) {
result += next.toString();
}
return result;
}
}
I have tried with the collection.sort method but, without luck, as i tried to use it on an list that i created myself, but it worked fine, when i just used the objects. Is there somehow special i need to do, if I want to acces the field of an object inside a node?
memberPlayer class:
public class memberPlayer implements Comparable<memberPlayer>{
private String firstName;
private String lastName;
private int age;
private String team;
}
You should implement the compareTo method in the Comparable interface to use a specific field.
#Override
public int compareTo(Object o) {
MemberPlayer player = (MemberPlayer)o;
return this.firstName.compareTo(player.firstName);
}
P:S Always use proper conventions when naming classes.

I Request Help on Implementing a General Tree in Java

I've come up with the following as an attempt to create a general tree in java:
import java.util.*;
public class GeneralNode<T>{
private T data = null;
private Vector<GeneralNode<T>> children =
new Vector<GeneralNode<T>>();
public GeneralNode(){
this(null);
}
public GeneralNode(T d){
data = d;
}
public Vector<GeneralNode<T>> getChildren(){
return children;
}
public void addChild(T d){
GeneralNode<T> c = new GeneralNode<T>(d);
this.children.add(c);
}
public void addChild(GeneralNode<T> c){
this.children.add(c);
}
public T getData(){
return data;
}
public void setData(T newData){
data = newData;
}
public boolean isLeaf(){
return(children.isEmpty());
}
public Vector getChildrenData(){
Vector<T> result = new Vector<T>();
for(int i = 0; i < children.size(); i++)
result.add(children.elementAt(i).getData());
return result;
}
}
This works great for storing information. It allows me to create a node and insert more nodes in that node, along with having one type of information in each node. Unfortunately, it seems like I can't reference a "parent" node with this class. Essentially, I'm nesting vectors within vectors, so I can't actually reference the node holding the node.
I'm sure I have to make a separate GeneralTree class in order to get this done, but I'm not sure how I'd go about doing so. I had the idea of assigning the root as a GeneralNode, and having a "previous" and "next" node as being the parent and children respectively. This is what I've come up with so far:
import java.util.*;
public class GeneralTree<T>{
private GeneralNode<T> root;
private GeneralNode<T> parent;
private GeneralNode<T> children;
public GeneralTree(){
this(null);
}
public GeneralTree(T d){
this(d, null);
}
/* I don't know what to do here. I want
* to assign a parent node to every
* tree I make, but if I keep the
* second parameter as GeneralNode<T>, wouldn't
* that mean I could only ever have one GeneralTree?
*/
public GeneralTree(T d, GeneralNode<T> p){
root = new GeneralNode<T>(d);
parent = p;
}
}
I've written comments on the constructor I'm confused on. I hope I've explained my problem well enough. If anyone can help me with this that'd be great.
As #JohnBollinger said, you can keep a reference of parent node inside each nodes. If you do that you must set parent nodes inside addChild methods.
import java.util.Vector;
public class GeneralNode<T>{
private T data = null;
private Vector<GeneralNode<T>> children =
new Vector<GeneralNode<T>>();
private GeneralNode<T> parentNode;
//constructors
private void setParent(GeneralNode<T> parentNode) {
this.parentNode = parentNode;
}
public void addChild(T d){
GeneralNode<T> c = new GeneralNode<T>(d);
c.setParent(this);
this.children.add(c);
}
public void addChild(GeneralNode<T> c){
c.setParent(this);
this.children.add(c);
}
//other methods
}

Cannot reference this before supertype constructor has been called

I'm attempting to implement a circular queue class in Java. And in doing so I had to created a node class to group together elements and pointers to the next node. Being circular, the nodes need to be able to point to themselves. However when I go to compile the code below, the compiler (javac) is telling me I'm doing something wrong with my constructors (namely lines 5 and 8) giving the error of the question's namesake, and I cannot figure out why it isn't working.
Any help and explanation of why my usage is incorrect is appreciated.
public class Node<Key>{
private Key key;
private Node<Key> next;
public Node(){
this(null, this);
}
public Node(Key k){
this(k, this);
}
public Node(Key k, Node<Key> node){
key = k;
next = node;
}
public boolean isEmpty(){return key == null;}
public Key getKey(){return key;}
public void setKey(Key k){key = k;}
public Node<Key> getNext(){return next;}
public void setNext(Node<Key> n){next = n;}
}
The compile error is
Cannot refer to 'this' nor 'super' while explicitly invoking a constructor
Basically, you cannot use "this" from inside "this(...)"
You cannot refer tho this (or super) in a constructor, so you should change your code like this:
public class Node<Key>{
private Key key;
private Node<Key> next;
public Node(){
key = null;
next = this;
}
public Node(final Key k){
key = null;
next = this;
}
public Node(final Key k, final Node<Key> node){
key = k;
next = node;
}
public boolean isEmpty(){return key == null;}
public Key getKey(){return key;}
public void setKey(final Key k){key = k;}
public Node<Key> getNext(){return next;}
public void setNext(final Node<Key> n){next = n;}
}
You dont need to pass it in all cases. since you can refer to it in the other construtor
Can not pass "this" as a parameter to call the constructor.

NullPointerException when i call a constructor with arguments

firstly, really sorry for my poor english.
i am trying to make a list of movies.
in main class i call the insert() method and in it i make an object of MovieListNode class in order to do what is needed.
class main{...
while( FileParsers.hasNextMovie() ){
MovieData movie = FileParsers.getNextMovie();
System.out.println( movie );
/* fill the movie lists here */
UnsortedMovieList vag=new UnsortedMovieList();
vag.insert(movie);
}
the insert method of unsortedmovielist:
class UnsortedMovieList{...
public void insert(MovieData data){
MovieListNode node=new MovieListNode(data.getId(),data.getTitle(),data.getYear(),data.getRating(),data.getVotes(),data.getDuration(),data.getGenres());
if(isEmpty()){
tail=node;
}else{
head.setPrevious(node);
}
node.setNext(head);
head=node;
size++;
}
and the MovieListNode class(sorry for the size):
public class MovieListNode {
private int id;
private String title;
private int year;
private double rating;
private int votes;
private int duration;
private ArrayList<genre_t> genres;
private int i=0;
private MovieListNode previous;
private MovieListNode next;
public MovieListNode(){}
public MovieListNode(int id, String title, int year, double rating, int votes, int duration, ArrayList<genre_t> genres) {
this.id=id;
this.title=title;
this.year=year;
this.rating=rating;
this.votes=votes;
this.duration=duration;
this.genres=genres;
}
public int getId() {return id;}
public String getTitle() {return title;}
public int getYear() {return year;}
public double getRating() {return rating;}
public int getVotes() {return votes;}
public int getDuration() {return duration;}
public ArrayList<genre_t> getGenres() {return genres;}
public MovieListNode getPrevious() {return previous;}
public MovieListNode getNext() {return next;}
public void setNext(MovieListNode next) {this.next=next;}
public void setPrevious(MovieListNode previous) {this.previous=previous;}
}
when i do this i get NullPointerException in line MovieListNode node=new MovieListNode(data.getId(),data.getTitle(),data.getYear(),data.getRating(),data.getVotes(),data.getDuration(),data.getGenres()).instead if i write 'MovielistNode node=new MovielistNode();' i dont get any errors but it's not what i want.
if anyone could help i would be grateful. thanks. (if u want more information about something in my code please let me know)
One or all of the fields in your MovieData object are null. You need to investigate your method:
FileParsers.getNextMovie();
You use this method to initialize an object of type MovieData If this method does not declare and initialize a MoveData object with a constructor that initializes all of the data fields, and then return that object, you will get a NullPointer when you try to call one of the getters
It is probably genres since the other fields have default initializations.
UPDATE:
In your Fileparsers class. I notice the code in the getNextMovie() method:
if( dataLine==null || genresLine==null )
return null;
}
It may be that your logic to readLine() is not being used correctly. So I suspect you may be ending up with null lines and therefore returning a null MovieData object. You should check if the next line is null before assigning it.

Categories

Resources