I am trying to print a binary tree by BFS.
my implementation is with a PriorityQueue.
in the beginning i insert root into PriorityQueue.
then in loop, i pull a node from PriorityQueue, print it, and insert his childs(if thay are not null) into PriorityQueue.
why when inserting the second node, i get this exception:
Exception in thread "main" java.lang.ClassCastException: Node cannot be cast to java.lang.Comparable
this is my code:
class main:
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Tree tree = new Tree();
}
}
class Node:
public class Node {
public Node(){}
public Node(int num)
{
value = num;
}
private int value;
private Node left;
private Node right;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
class tree:
public class Tree {
private Node root;
public Tree()
{
root = new Node(5);
Node node2 = new Node(2);
Node node10 = new Node(10);
Node node8 = new Node(8);
Node node6 = new Node(6);
Node node15 = new Node(15);
root.setRight(node10);
root.setLeft(node2);
node10.setRight(node15);
node10.setLeft(node8);
node8.setLeft(node6);
printToWidth(root);
}
public void printToWidth(Node node)
{
PriorityQueue<Node> queue = new PriorityQueue<Node>();
queue.add(node);
while( !(queue.isEmpty()))
{
Node n = queue.poll();
System.out.println(n.getValue());
if (n.getLeft() != null)
queue.add(n.getLeft());
if (n.getRight() != null)
queue.add(n.getRight());
}
System.out.println("end printToWidth");
}
}
You've got two options:
Make Node implement Comparable<Node>, so that the elements can be inserted according to their natural ordering. This is likely the easier of the two.
public int compareTo(Node other) {
return value - other.getValue();
}
Use a custom Comparator<Node> and supply a compare method there, with an initial capacity.
PriorityQueue<Node> queue = new PriorityQueue<Node>(10, new Comparator<Node>() {
public int compare(Node left, Node right) {
return left.getValue() - other.getValue();
}
});
The exception is telling you, make Node implement Comparable<Node>.
You can insert the first node because it has nothing to compare to, so the comparison is not needed.
Related
An abstract binary tree is to be created using a generic class. Each node has a string value as well as an initialCalculatedValue value. No changes should be made to the main class and a static inner class is to be included in the generic class. I'd like some advice on my code, as the main class is giving me error on accessing 'timesVisited' and 'values'. My code can't seem to access those variables.
Main class code:
public class Main{
public static void main(String[] args) {
WalkableTree<String, Integer> ast = new WalkableTree<>(0);
WalkableTree.Node<String, Integer> plus = ast.setRoot("+");
plus.setRightChild("20");
WalkableTree.Node<String, Integer> multiply = plus.setLeftChild("*");
multiply.setLeftChild("10");
WalkableTree.Node<String, Integer> bracketedPlus = multiply.setRightChild("+");
bracketedPlus.setLeftChild("3");
bracketedPlus.setRightChild("4");
// write visitor to display pre-order
System.out.println("Pre-order traversal:");
ast.walk(current -> {
if(current.timesVisited == 2)
System.out.print(current.value + " ");
});
System.out.println();
// write visitor to display in-order
System.out.println("In-order traversal:");
ast.walk(current -> {
if(current.timesVisited == 3)
System.out.print(current.value + " ");
});
System.out.println();
// write visitor to display post-order
System.out.println("Post-order traversal:");
ast.walk(current -> {
if(current.timesVisited == 4)
System.out.print(current.value + " ");
});
System.out.println();
}
}
Functional interface:
#FunctionalInterface
public interface Visitor<N> {
public void visit(N node);
}
Generic class:
public class WalkableTree <T, R> {
private T root = null;
private R initialCalculatedValue;
public static Node current;
public WalkableTree(R initialCalculatedValue) {
this.initialCalculatedValue = initialCalculatedValue;
}
public Node getRoot() {
return (Node) root;
}
public Node setRoot(T value) {
current = new Node(null,null,null,value,null,0);
return current;
}
public R getInitialCalculatedValue() {
return initialCalculatedValue;
}
public void setInitialCalculatedValue(R initialCalculatedValue) {
this.initialCalculatedValue = initialCalculatedValue;
}
protected void reset(Node node) {
node.timesVisited = 0;
node.calculatedValue = initialCalculatedValue;
reset((Node) node.leftChild);
reset((Node) node.rightChild);
}
public Node nextNode(Node node) {
node.timesVisited++;
if(node.timesVisited == 1)
return node;
if(node.timesVisited == 2)
return (Node) node.leftChild;
if(node.timesVisited == 3)
return (Node) node.rightChild;
if(node.timesVisited == 4)
return (Node) node.getParent();
return node;
}
public void walk(Visitor visitor) {
//Reset all the nodes in the tree
reset((Node) root);
//Set the current node to visit at the root of the tree
visitor.visit(root);
//Walking through the tree as long as the current node still exists
//If current node exists, let the visitor object visit the current node
//Current node is set to the next node using nextNode() method
while (this.current == current)
{
nextNode(current);
}
}
public static class Node<T, R> {
//Variables
Object leftChild;
Object rightChild;
Object parent;
T value;
R calculatedValue;
int timesVisited = 0;
public Node(Object leftChild, Object rightChild, Object parent, T value, R calculatedValue, int timesVisited) {
this.leftChild = leftChild;
this.rightChild = rightChild;
this.parent = parent;
this.value = value;
this.calculatedValue = calculatedValue;
this.timesVisited = timesVisited;
}
public Object getLeftChild() {
return leftChild;
}
public Node setLeftChild(T value) {
Node newLeft = new Node(null,null, current,value,0,0);
current = newLeft;
return current;
}
public Object getRightChild() {
return rightChild;
}
public Node setRightChild(T value) {
Node newRight = new Node(null,null, current,value,0,0);
current = newRight;
return current;
}
public Object getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public R getCalculatedValue() {
return calculatedValue;
}
public void setCalculatedValue(R calculatedValue) {
this.calculatedValue = calculatedValue;
}
public int getTimesVisited() {
return timesVisited;
}
public void setTimesVisited(int timesVisited) {
this.timesVisited = timesVisited;
}
}
}
Update the method in WalkableTree as below:
public void walk(Visitor<Node> visitor) {
//Reset all the nodes in the tree
reset((Node) root);
//Set the current node to visit at the root of the tree
visitor.visit((Node) root);
//Walking through the tree as long as the current node still exists
//If current node exists, let the visitor object visit the current node
//Current node is set to the next node using nextNode() method
while (this.current == current)
{
nextNode(current);
}
}
I am attempting to implement a linked list that uses a node class containing head, tail, and current nodes. Part of the linked list is an add method that should add a value to the end of the current node in the list just like an actual linked list would. My issue is that it only works for the first node and then just stops there. For example, in my main I tried testing the code by calling add(1); and add(2);. The console shows me 1 but that's all. I'm unsure if the error is in my add method, toString method, or node class.
I'll also add that I tested whether the correct values were being assigned to "current" in either case, and they were. This has led me to wonder if it's the toString that is the root of the issues, however no matter how much I try I can't change it to make any improvements.
I've hoping fresh eyes may be able to find any blaring issues that may exist.
Add method:
public void add(int val){
if(current != null){
Node nextNode = new Node(val, current);
current = nextNode;
tail = nextNode;
}
else{
head = tail = new Node(val, null);
current = head;
}
}
Node class:
public class Node{
public int data;
public Node next;
public Node(int d, Node next) {
this.data = d;
this.next = next;
}
}
toString:
public String toString(){
for(Node x = head; x != null; x = x.next){
System.out.println(x.data);
}
All:
public class IntLList extends IntList{
public IntLList(){
}
public class Node{
public int data;
public Node next;
public Node(int d, Node next) {
this.data = d;
this.next = next;
}
}
Node head = null;
Node tail = null;
Node current = null;
public void add(int val){
if(current != null){
Node nextNode = new Node(val, current);
current = nextNode;
tail = nextNode;
}
else{
head = tail = new Node(val, null);
current = head;
}
}
public int get(int index){
return 0;
}
public void set(int index, int val){
}
public void remove(int index) throws ArrayIndexOutOfBoundsException{
}
public int size(){
return 0;
}
public String toString(){
for(Node x = head; x != null; x = x.next){
System.out.println(x.data);
}
return "temp";
}
public void removeLast(){
}
public boolean isEmpty(){
boolean isEmpty = false;
if(head == null){
isEmpty = true;
}
return isEmpty;
}
public void clear(){
}
public static void main(String[] args) {
IntLList i = new IntLList();
i.add(1);
i.add(2);
i.toString();
}
}
Make the following changes:
public class Node{
public int data;
public Node next;
public Node(int d, Node next) {
this.data = d;
this.next = NULL; // this is to set the next node of current node to null
if(next!=NULL)
next.next=this; // this is to set the previous node to point to current node
}
}
I need to implement a Node class, where the basic methods are: getItem(), getNext(), setItem() and setNext(). I want the nodes to be able to store at least the default integer range in Java as the “item”; the “next” should be a reference or pointer to the next Node in a linked list, or the special Node NIL if this is the last node in the list.I also want to implement a two-argument constructor which initializes instances with the given item (first argument) and next node (second argument) , I've kind of hit a brick wall and need some guidance about implementing this , any ideas ?
I have this so far:
class Node {
public Node(Object o, Node n) {
}
public static final Node NIL = new Node(Node.NIL, Node.NIL);
public Object getItem() {
return null;
}
public Node getNext() {
return null;
}
public void setItem(Object o) {
}
public void setNext(Node n) {
}
}
While implementing the custom LinkedList/Tree, we need Node. Here is demo of creating Node and LinkedList. I have not put in all the logic. Just basic skeleton is here and you can then add more on yourself.
I can give you a quick hint on how to do that:
Class Node{
//these are private class attributes, you need getter and setter to alter them.
private int item;
private Node nextNode;
//this is a constructor with a parameter
public Node(int item)
{
this.item = item;
this.nextNode = null;
}
// a setter for your item
public void setItem(int newItem)
{
this.item = newItem;
}
// this is a getter for your item
public int getItem()
{
return this.item;
}
}
You can create a Node object by calling:
Node newNode = Node(2);
This is not a complete solution for your problem, the two parameter constructor and the last node link are missing, but this should lead you in the correct direction.
Below is a simple example of the Node implementation, (i renamed Item to Value for readability purpose). It has to be implemented somehow like this, because methods signatures seems to be imposed to you. But keep in mind that this is definely not the best way to implement a LinkedList.
public class Node {
public static final Node NIL = null;
private Integer value;
private Integer next;
public Node(Integer value, Node next) {
this.value = value;
this.next = next;
}
public Integer getValue() {
return this.value;
}
public Node getNext() {
return this.next;
}
public void setValue(Integer value) {
this.value = value;
}
public void setNext(Node next) {
this.next = next;
}
public boolean isLastNode() {
return this.next == Node.NIL || Node;
}
}
public class App {
public static void main(String[] args) {
Node lastNode = new Node(92, Node.NIL);
Node secondNode = new Node(64, lastNode);
Node firstNode = new Node(42, secondNode);
Node iterator = firstNode;
do () {
System.out.println("node value : " + iterator.getValue());
iterator = iterator.getNext();
} while (iterator == null || !iterator.isLastNode());
}
}
The node class that will be implemented changes according to the linked list you want to implement. If the linked list you are going to implement is circular, then you could just do the following:
public class Node {
int data;
Node next = null;
public Node(int data){
this.data = data;
}
}
Then how are you going to implement the next node?
You are going to do it in the add method of the circularLinkedList class. You can do it as follows:
import java.util.*;
public class CircularLinkedList {
public CircularLinkedList() {}
public Node head = null;
public Node tail = null;
public void add(int data) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
}
else {
tail.next = newNode;
}
tail = newNode;
tail.next = head;
}
public void displayList() {
System.out.println("Nodes of the circular linked list: ");
Node current = head;
if(head == null) {
System.out.println("Empty list...");
}
else {
do {
System.out.print(" " + current.data);
current = current.next;
}while(current != head);
System.out.println();
}
}
}
When I print out the elements of this Binary Tree using my inOrder method, it prints: 0 0 0 0 0 0
Here is my Code:
public class BST {
class Node {
int data;
Node left;
Node right;
public Node(int data) {
data = data;
left = null;
right = null;
}
public Node root;
/**
* Method to insert a new node in order
* in our binary search tree
*/
public void insert(int data) {
root = insert(root, data);
}
public Node insert(Node node, int data){
if(node==null){
node = new Node(data);
}else if (data < node.data){
node.left = insert(node.left, data);
}else{
node.right = insert(node.right, data);
}
return node;
}
/**
Prints the node values in the "inorder" order.
*/
public void inOrder() {
inOrder(root);
}
private void inOrder(Node node) {
if (node == null)
return;
inOrder(node.left());
System.out.print(node.data + " ");
inOrder(node.right);
}
}
Main class:
public class Main {
public static void main(String[] args) {
BST tree = new BST();
tree.insert(6);
tree.insert(4);
tree.insert(8);
tree.insert(2);
tree.insert(1);
tree.insert(5);
tree.inOrder();
}
}
I have a feeling that it is something wrong in my insert method, I just can't figure out what. Any help in the right direction would be great, and sorry for being a noob!
In class Node your constructor is setting the constructor argument to itself instead of initializing the class variable.
Use the keyword this in your ctor to distinguish from constructor arguments and class variable.
Example:
public class Pair
{
private int left;
private int right;
public Pair(int left, int right) {
// the following 2 lines don't do anything
// it set's the argument "left = left" which is silly...
left = left;
right = right;
// with the `this` keyword we can correctly initialize our class properties
// and avoid name collision
this.left = left;
this.right = right;
}
}
I've a university project about creating two classes, Tree class and Node class, to implement a k-ary tree using Java.
In the class Tree, there should be a constructor which recives as input an int that indicates the tree arity.
I've worked before with general trees and this was my result:
Class tree: *
Class node: *
I absolutely don't know where and how to start to build this project (as I don't know how to manage the arity, maybe with ArrayList?).
Any advice and suggestions will be greatly appreciated :)
Thanks in advance.
Here are the new versions of the classes, with the methods that you needed.
Node:
import java.util.ArrayList;
import java.util.List;
public class Node {
public Node parent; // The parent of the current node
public List<Node> children; // The children of the current node
public Object info;
public static int maxNrOfChildren; // Equal to the k-arity;
public Node (Object info)
{
this.info=info;
children = new ArrayList<Node>(maxNrOfChildren);
}
public void addChild(Node childNode, int position)
// You must take care so that future insertions don't override a child on i-th position
{
if(position>=maxNrOfChildren-1)
{
// Throw some error
}
else
{
System.out.println("this.children="+this.children);
if(this.children.get(position)!=null)
{
// There is alerady a child node on this position; throw some error;
}
else
{
childNode.parent=this;
this.children.set(position, childNode);
}
}
}
}
Tree:
import java.util.ArrayList;
import java.util.List;
public class Tree {
public Node root;
public Tree(int kArity)
{
Node.maxNrOfChildren=kArity;
}
public void addRoot(Object info)
{
root=new Node(info);
root.parent=null;
root.children=new ArrayList<Node>(Node.maxNrOfChildren);
}
public void addNewNodeVasithChildOfNodeU(Node u, Object info, int i)
{
Node child=new Node(info);
u.addChild(child, i);
}
// I've made the above two methods of type void, not Node, because
// I see no reason in returning anything; however, you can override by calling
//'return root;' or 'return child;'
public int numberOfNodesInTree(Node rootNode){
int count=0;
count++;
if(rootNode.children.size()!=0) {
for(Node ch : rootNode.children)
count=count+numberOfNodesInTree(ch);
}
return count;
}
public int numberOfNodesInTree()
{
return numberOfNodesInTree(this.root);
}
public void changeRoot(Node newRoot, int i)
{
Node oldRoot=this.root;
newRoot.parent=null;
newRoot.addChild(oldRoot, i);
oldRoot.parent=newRoot;
this.root=newRoot;
}
public static void main(String args[])
{
Tree tree=new Tree(3);
Node a = new Node("a");
Node b = new Node("b");
Node c = new Node("c");
tree.addRoot("root");
tree.root.addChild(a,0);
a.addChild(b,0);
tree.root.addChild(c,1);
System.out.println(tree.numberOfNodesInTree(tree.root));
}
}
The logic is correct, but I am getting some Java-related error when I run the main method and I haven't yet figured out what the problem is.
this can be a starting point:
Node Class
import java.util.ArrayList;
import java.util.List;
public class Node {
public Node parent;//the parent of the current node
public List<Node> children = new ArrayList<Node>();//the children of the current node
public String name;//or any other property that the node should contain, like 'info'
public static int maxNrOfChildren;//equal to the k-arity;
public Node (String nodeName)
{
name=nodeName;
}
public void addChild(Node childNode)
{
if(this.children.size()>=maxNrOfChildren)
{
//do nothing (just don't add another node), or throw an error
}
else
{
childNode.parent=this;
this.children.add(childNode);
}
}
}
Tree Class
import java.util.ArrayList;
import java.util.List;
public class Tree {
public Node root = new Node("root");
public Tree(int kArity)
{
Node.maxNrOfChildren=kArity;
root.parent=null;
}
public void traverseTree(Node rootNode)//depth first
{
System.out.println(rootNode.name);
if(rootNode.children.size()!=0)
for(Node ch : rootNode.children)
traverseTree(ch);
}
public static void main(String args[])
{
Tree tree=new Tree(3);
Node a = new Node("a");
Node b = new Node("b");
Node c = new Node("c");
tree.root.addChild(a);
a.addChild(b);
tree.root.addChild(c);
tree.traverseTree(tree.root);
}
}
Please give further details about your project specifications, otherwise i can't figure out which kind of functionality you need within these classes
The idea behind creating a k-array, is that this is not a conventional structure like a list or a set, the node is like an element in a linked list, it point to the n other child node and can also point to the parent, whant determine what should be the child or the parent in that sctructure is an entire different question. As for the list of child in the node you can use any structure you whant ArrayList most likely will be a good fit. The choice of a structure depend on many factors like size, how often it will be accessed does it need to be sorted etc.
Have a look at this. Hope it helps.
import java.util.ArrayList;
public class Nary
{
public static Node root;
public static int insert(Node rootNode, int parentId, ArrayList<Node> nodeToAdd)
{
if(rootNode == null)
return 0;
if(rootNode.children == null)
rootNode.children = new ArrayList<Node>();
if(rootNode.id == parentId)
{
for(int i =0; i < nodeToAdd.size(); i++)
{
Node node = nodeToAdd.get(i);
node.parent = rootNode;
rootNode.children.add(node);
}
return 1;
}
else
{
for(int i = 0; i < rootNode.children.size(); i++)
{
int resultFlag = insert(rootNode.children.get(i), parentId, nodeToAdd);
if(resultFlag == 1)
{
return 1;
}
}
}
return -1;
}
public static void traverse(Node root)
{
if(root == null)
{
return;
}
System.out.println(root.data + " " + root.id );
for(Node child : root.children)
{
traverse(child);
}
}
public static void main(String[] args) {
// Insertion
root = new Node(0, "root");
int parentId = root.id;
Node Bread = new Node(1, "Bread");
Node Milk = new Node(2, "Milk");
Node Meat = new Node(3, "Meat");
Node Eggs = new Node(4, "Eggs");
ArrayList<Node> nodeList = new ArrayList<Node>();
nodeList.add(Bread);
nodeList.add(Milk);
nodeList.add(Meat);
nodeList.add(Eggs);
insert(root, parentId, nodeList);
// Add children for Bread
parentId = Bread.id;
Node Bread0 = new Node(11, "Whole-Wheat");
Node Bread1 = new Node(12, "Whole-Grain");
Node Bread2 = new Node(13, "Italian");
ArrayList<Node> nodeList1 = new ArrayList<Node>();
nodeList1.add(Bread0);
nodeList1.add(Bread1);
nodeList1.add(Bread2);
insert(root, parentId, nodeList1);
Add children for Milk
parentId = Milk.id;
Node Milk0 = new Node(21, "Whole");
Node Milk1 = new Node(22, "skim");
Node Milk2 = new Node(23, "Almond");
ArrayList<Node> nodeList2 = new ArrayList<Node>();
nodeList2.add(Milk0);
nodeList2.add(Milk1);
nodeList2.add(Milk2);
insert(root, parentId, nodeList2);
traverse(root);
}
}
class Node{
int id;
String data;
Node parent;
ArrayList<Node> children;
public Node(int id, String data)
{
this.id = id;
this.data = data;
}
}