I wrote a java Node class. It has the basics.
public class Node{
PuzzleState ps;
Node child;
public Node(PuzzleState ps){
this.ps = ps;
}
public PuzzleState getState(){
return this.ps;
}
public void setChild(Node n){
this.child = n;
}
public Node getChild(){
return this.child;
}
}
I created a new Node like this:
Node up = new Node(puzzle);
This will change all my other nodes to have all the characteristics of Node up. Please help me. I think I may be using the modifiers wrong (i.e. private, public, static)
Related
I am still learning and currently trying to implement DoublyLinkedLists with nested STATIC classes and getting the error below:
No enclosing instance of the type OuterClass.StaticNestedClass is accessible in scope
Actual error:
No enclosing instance of the type SolutionDLL.Node is accessible in scope
I have two STATIC nested classes inside the outer class SolutionDLL class:
class SolutionDLL {
public static class Node {
private Object element;
private Node next;
private Node previous;
Node(Object elementIn, Node nextNodeIn, Node prevNodeIn) {
element = elementIn;
next = nextNodeIn;
previous = prevNodeIn;
}
public Object getElement() {
return element;
}
public Node getNext() {
return next;
}
public Node getPrevious() {
return previous;
}
}
public static class DLList {
public void addFirst(Node n) {
SolutionDLL.Node tempNode = new SolutionDLL.Node(
SolutionDLL.Node.this.getElement(),
SolutionDLL.Node.this.getNext(),
SolutionDLL.Node.this.getPrevious());
// do something
}
}
}
No matter if i call like this:
SolutionDLL.Node.this.getElement()
of like this:
Node.this.getElement()
I still get the error. I had the skeleton code given and this is the first time I am implementing with nested classes. So any help would be well appreciated.
Thanks!
SolutionDLL.Node, just like any class, does not have this field. this field is only available inside object and its inner classes of that object class.
Change addFirst to get the values fomr n node instead:
public static class DLList {
private Node firstNode = null;
public void addFirst(Node n) {
//do something with the first node before it is assigned to the n
if (firstNode != null){
SolutionDLL.Node tempNode = new SolutionDLL.Node(
firstNode.getElement(),
firstNode.getNext(),
firstNode.getPrevious());
}
firstNode = n;
// do something
}
}
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
}
I am trying to implement the NullObject design pattern on my class Node:
class Node{
Node nextNode;
char key;
Node prevNode;
/*
Would like to initialize nextNode and prevNode to instance of
NullNode, something like this (I know what I am doing is wrong)
*/
Node() {
nextNode = new NullNode();
prevNode = new NullNode();
}
}
class NullNode extends Node {
....
}
With this code I get a StackOverflowError Exception. How can I tackle this issue?
You are getting a StackOverflow because the parent constructor is always called (see also: https://stackoverflow.com/a/527069/664108). In your case this results in endless recursion.
To avoid that, you will have to add a check in the Node constructor and call it explicitly from the NullNode constructor:
public class Node
{
Node nextNode;
char key;
Node prevNode;
Node() {
Node(true);
}
Node(boolean createNullNodes) {
if (createNullNodes) {
nextNode = new NullNode();
prevNode = new NullNode();
}
}
}
public class NullNode extends Node
{
NullNode() {
super(false);
}
}
A better solution for the NullObject pattern is using interfaces. This eliminates the constructor problem and also allows to remove the not needed nextNode and prevNode variables from the NullNode.
Example with interface:
public interface INode
{
public char getKey();
public INode getNext();
public INode getPrev();
// ...
}
public class Node implements INode
{
Node nextNode;
char key;
Node prevNode;
Node() {
nextNode = new NullNode();
prevNode = new NullNode();
}
public char getKey() {
return key;
}
public INode getNext() {
return nextNode;
}
public INode getPrev() {
return prevNode;
}
}
public class NullNode implements INode
{
public char getKey() {
return null;
}
public INode getNext() {
return this;
}
public INode getPrev() {
return this;
}
}
Normally we do not reference the Subclass in the Suerclass, this somehow breaks the inheritance relation.
In your code there is something even worse that will cause a StackoverflowException because the superclass creates an object with the default constructor of the subclass which in turns calls the default constructor of the superclass and it will go infinitely until your program crashes.
You can see an implementation of the Null Object Pattern here
Try this
public clas Node
{
Node nextNode;
char key;
Node prevNode;
Node() {
this(true);
}
Node(boolean createNullNodes) {
if (createNullNodes) {
nextNode = new NullNode();
prevNode = new NullNode();
}
}
}
public class NullNode extends Node
{
NullNode() {
super(false);
}
}
To call one constructor from another constructor use this(args)... you cannot call it directly
Please find a Tree class definition below.
public class Tree<T>{
private T head;
private List<Tree<T>> leafs = new ArrayList<>();
private Tree<T> parent = null;
private Map<T, Tree<T>> locate = new HashMap<>();
public Tree(T head) {
this.head = head;
locate.put(head, this);
}
public void addLeaf(T root, T leaf) {
if (locate.containsKey(root)) {
locate.get(root).addLeaf(leaf);
} else {
addLeaf(root).addLeaf(leaf);
}
}
public Tree<T> addLeaf(T leaf) {
Tree<T> t = new Tree<>(leaf);
leafs.add(t);
t.parent = this;
t.locate = this.locate;
locate.put(leaf, t);
return t;
}
}
The Tree class object is created in another class and nodes are added in a straightforward way (using the addLeaf(node) function). This process builds the tree alright. Would someone be able to suggest a DFS function implementation on the constructed tree adhering to the above class definition?
Thank you.
This is what I've tried. Yes, it gives me meaningless results.
protected void DFS() {
for(Tree<T> child : leafs) {
DFS();
System.out.println(child);
}
}
The code is from the third comment at link
protected void DFS() {
for(Tree<T> child : leafs) {
child.DFS();
System.out.println(child.head);
}
}
resolved!
You're close. The print should be the value of the node, and the recursion should be on the child.
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.