Null pointer working with nodes - java

I have a problem comparing nodes (of binary tree) to null
Say node is a new root of the tree, with key=5.
In the constructor I set node's left, right and parent to be null
(fields: private Node left=null,right=null,parent=null;
constructor: this.key=key)
When I print the node's left child (same as for the right and the parent) I get null as expected.
However, node.left==null (or node.getLeft()==null) gets me false. why?
Here's the code of node class:
public class Node{
private Node parent = null, left = null, right = null;
private int key;
public Node(int key) {
this.key = key;
}
public Node getParent() {
return parent;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
public void setParent(Node parent) {
this.parent = parent;
}
public void setLeft(Node child) {
this.left = child;
}
public void setRight(Node child) {
this.right = child;
}
public void setKey(int key) {
this.key = key;
}
}

Related

How to create an assignFirst method with Nodes in a BinarySearchTree?

I have a binarySearch Tree and I want to create a method assignFirst.
This method should find the node in the tree with the smallest value and
update the tree's "first" attribute accordingly.
I have a lot of methods, but I don't want to include all of them in here, since I want to keep it short and simple.
Therefore, I will include the class and some features inside that class.
public class BinarySearchTree<E extends Comparable<E>>
{
private BSTNode<E> root; // root of overall tree
private int numElements;
private BSTNode<E> first;
// post: constructs an empty search tree
public BinarySearchTree()
{
this.root = null;
this.numElements = 0;
}
private void assignFirst()
{
if (root.left == null)
{
first.data = root.data;
}
else
{
first.data = root.left.data;
}
}
public class Iterator
{
private BSTNode<E> currentNode;
public Iterator()
{
currentNode = first;
}
public boolean hasNext()
{
return currentNode != null;
}
public E next()
{
E value = currentNode.data;
currentNode = currentNode.next;
return value;
}
}
private static class BSTNode<E>
{
public E data;
public BSTNode<E> left;
public BSTNode<E> right;
public BSTNode<E> parent;
public BSTNode<E> next;
public BSTNode(E data)
{
this(data, null, null, null, null);
}
public BSTNode(E data, BSTNode<E> left, BSTNode<E> right, BSTNode<E> parent, BSTNode<E> next)
{
this.data = data;
this.left = left;
this.right = right;
this.parent = parent;
this.next = next;
}
}
}
I updated my method look like this. I'm still uncertain if this is the correct way of doing it.
private void assignFirst()
{
if (first.left != null)
{
first = first.left;
}
else
{
first = root;
}
}
I figured it out. I wrote it in like this.
private void assignFirst()
{
BSTNode<E> node = root;
while(node.left != null)
{
node = node.left;
}
first = node;
}

Get the parent path of Node in a tree

I am using the following code to convert a flat structure like:
test/test2/test3
test/test5/test2
test/test7/test5/test4
test/test7/test5/test9
into a tree like:
test
| | |
test2 test5 test7
| | |
test3 test2 test5
| |
test4 test9
The code:
import java.util.*;
class Tree
{
class Node
{
String data;
ArrayList<Node> children;
public Node(String data)
{
this.data = data;
children = new ArrayList<Node>();
}
public ArrayList<Node> getChildren()
{
return children;
}
public Node getChild(String data)
{
for(Node n : children)
if(n.data.equals(data))
return n;
return null;
}
}
private Node root;
public Tree()
{
root = new Node("");
}
public boolean isEmpty()
{
return root==null;
}
public void add(String str)
{
Node current = root;
StringTokenizer s = new StringTokenizer(str, "/");
while(s.hasMoreElements())
{
str = (String)s.nextElement();
Node child = current.getChild(str);
if(child==null)
{
current.children.add(new Node(str));
child = current.getChild(str);
}
current = child;
}
}
public void get()
{
return root;
}
}
I use the "add" function to split the above flat paths to a tree and it works nicely and I am able to navigate forward. Though, I want to be able to navigate to the Node with a given path and also when I navigate to some Node, I want to be able to trace it to the root element. For example, if I navigate from test -> test2 -> test3, I want to get the path from the root like test/test2/test3.
I am new to Trees and the topic is confusing me a bit, your help is highly appreciated.
Edit: Added a visual representation.
public class Tree {
private final Node root = new Node(null, null);
public boolean isEmpty() {
return root.children.isEmpty();
}
public void add(String path) {
Node parent = root;
for (String data : path.split("/")) {
Node node = parent.getChild(data);
if (node == null)
parent.children.add(node = new Node(data, parent));
parent = node;
}
}
public Node get(String path) {
Node parent = root;
for (String data : path.split("/")) {
Node node = parent.getChild(data);
if (node == null)
return null;
parent = node;
}
return parent;
}
public static final class Node {
private final String data;
private final Node parent;
private final List<Node> children = new LinkedList<>();
public Node(String data, Node parent) {
this.data = data;
this.parent = parent;
}
public List<Node> getChildren() {
return Collections.unmodifiableList(children);
}
public Node getChild(String data) {
for (Node node : children)
if (node.data.equals(data))
return node;
return null;
}
public String getPath() {
Deque<String> nodes = new LinkedList<>();
Node node = this;
while (node.parent != null) {
nodes.addFirst(node.data);
node = node.parent;
}
return String.join("/", nodes);
}
#Override
public String toString() {
return data;
}
}
public static void main(String... args) {
Tree tree = new Tree();
tree.add("test/test2/test3");
tree.add("test/test5/test2");
tree.add("test/test7/test5/test4");
tree.add("test/test7/test5/test9");
Node node = tree.get("test/test7/test5/test9");
String path = node.getPath();
}
}
A simple way is to keep track of the parent node, then just follow the parents up the tree from the child:
Node currentNode = ...
ArrayList<Node> path = new ArrayList<>();
while(currentNode != null){
path.add(currentNode);
currentNode = currentNode.getParent();
}
Collections.reverse(path);
So your Node class would need a new constructor:
class Node {
String data;
ArrayList<Node> children;
Node parent;
Node(Node parent, String data){
// ...
}
// ...
// Null if this is the root, else returns the parent node
public Node getParent(){ return parent; }
}

How to get the level of a leaf in a non-binary tree

I have constructed a Tree class as shown below:
public class Node {
private int label;
private ArrayList<Node> children;
private Node parent;
public Node(int label) {
this.label = label;
this.children = new ArrayList<Node>();
this.parent = null;
}
public void addChild(Node child) {
this.children.add(child);
}
public int getLabel() {
return this.label;
}
public ArrayList<Node> getChildren() {
return this.children;
}
public Node getParent() {
return this.parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
}
Assuming that I have a non binary Tree:
1
|
9
/ | \
3 0 7
How can I write a method in order to get the level of a leaf (say node labelled with 7) in a non-binary Tree?
public int getLevel() {
if (parent == null) return 0;
// Additional code is needed here
}
The level is often called the depth or height.
public int getLevel(){
Node temp = parent;
int depth = 0;
while(temp != null){
depth++;
temp = temp.parent;
}
return depth;
}
This will not work if there is a cycle of course, but there shouldn't be one in a tree anyways.

How to define a node class for multiple tree nodes that have 4 values assigned to it?

I am extremely new to java, and all my other searches lead to something more complex than my given question so I was wondering how i may go about this? i would like for my tree nodes to have consist of the following fields: parent, left, right and data.
Since you're new to Java the most basic structure would be like this:
public class Node {
private Node parent, left, right;
private Integer data;
public Node(Node parent, Node left, Node right, Integer data) {
this.parent = parent;
this.left = left;
this.right = right;
this.data = data;
}
public Node getParent() { return this.parent; }
public Node getLeft() { return this.left; }
public Node getRight() { return this.right; }
public Integer getData() { return this.data; }
public void setParent(Node parent) { this.parent = parent; }
public void setLeft(Node left) { this.left = left; }
public void setRight(Node right) { this.right = right; }
public void setData(Integer data) { this.data = data; }
}
If you want to take it one step further and learn more about Object-Oriented Programming I would look into generics.
public class Node<T extends Comparable<T>> {
private Node parent, left, right;
private T data;
// Getters, setters, compare methods here
}
This will let you declare a Node<Integer>, Node<String>, Node<CustomClass> to let you not be restricted to a certain type of data. You'll want to do extend Comparable<T> so that you can easily compare objects when doing an insert(), and other Tree functions.

Raw type Binary Search Tree issue in Java SE 1.7

I'm trying to build an raw type BST, with Comparable<T>. The thing is somehow my declarations do something wrong, because I use in Node class type Comparable<type> and in BST class it errors with
The method setParent(Node<Comparable<Comparable<type>>>) in the type
Node<Comparable<type>> is not applicable for the arguments (Node<Comparable<type>>)
BinarySearchTree.java /lab2/src line 22 Java Problem
Node.java:
public class Node <type> {
private Comparable<type> key;
private Node <Comparable<type>> parent;
private Node <Comparable<type>> leftChild;
private Node <Comparable<type>> rightChild;
public Node(Comparable<type> key, Node <Comparable<type>> leftChild, Node <Comparable<type>> rightChild) {
this.setKey(key);
this.setLeftChild(leftChild);
this.setRightChild(rightChild);
}
public void setKey(Comparable<type> key) {
this.key = key;
}
public Comparable<type> getKey() {
return key;
}
public void setParent(Node<Comparable<type>> y) {
this.parent = y;
}
public Node <Comparable<type>> getParent() {
return parent;
}
public void setLeftChild(Node <Comparable<type>> leftChild) {
this.leftChild = leftChild;
}
public Node <Comparable<type>> getLeftChild() {
return leftChild;
}
public void setRightChild(Node <Comparable<type>> rightChild) {
this.rightChild = rightChild;
}
public Node <Comparable<type>> getRightChild() {
return rightChild;
}
}
BinarySearchTree.java:
import java.util.Iterator;
public class BinarySearchTree<type> implements SortedSet<type> {
private Node <Comparable<type>> root;
public void insert(Node <Comparable<type>> z) {
Node <Comparable<type>> y = null;
Node <Comparable<type>> x = root;
while (x != null) {
y = x;
if (z.getKey() < x.getKey()) { // ERROR '<' is undefined for type...
x = x.getLeftChild(); // PARAM TYPE ERROR
} else {
x = x.getRightChild(); // PARAM TYPE ERROR
}
}
z.setParent(y);
if (y == null) {
root = z;
} else if (z.getKey() < y.getKey()) {
y.setLeftChild(z);
} else {
y.setRightChild(z);
}
}
Consider to refactoring to the following code
import java.util.SortedSet;
public abstract class BinarySearchTree<T extends Comparable<T>> implements SortedSet<T> {
private Node<T> root;
class Node<T extends Comparable<T>> {
private T key;
private Node<T> parent;
private Node<T> leftChild;
private Node<T> rightChild;
public Node(T key, Node<T> leftChild, Node<T> rightChild) {
this.setKey(key);
this.setLeftChild(leftChild);
this.setRightChild(rightChild);
}
public void setKey(T key) {
this.key = key;
}
public T getKey() {
return key;
}
public void setParent(Node<T> y) {
this.parent = y;
}
public Node <T> getParent() {
return parent;
}
public void setLeftChild(Node <T> leftChild) {
this.leftChild = leftChild;
}
public Node <T> getLeftChild() {
return leftChild;
}
public void setRightChild(Node <T> rightChild) {
this.rightChild = rightChild;
}
public Node <T> getRightChild() {
return rightChild;
}
}
public void insert(Node<T> z) {
Node<T> y = null;
Node<T> x = root;
while (x != null) {
y = x;
if (z.getKey().compareTo(x.getKey()) < 0) {
x = x.getLeftChild();
} else {
x = x.getRightChild();
}
}
z.setParent(y);
if (y == null) {
root = z;
} else if (z.getKey().compareTo((T) y.getKey()) <0) {
y.setLeftChild(z);
} else {
y.setRightChild(z);
}
}
}

Categories