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;
}
}
Related
this is the node class for my n-ary tree
import java.util.ArrayList;
public class Node{
public String label;
public ArrayList<Node> children;
public Node(String label){
this.label =label;
this.children = new ArrayList<Node>();
}
public void addChild(String child){
Node childNode = new Node(child);
this.children.add(childNode);
}
public void addChild(Node child){
this.children.add(child);
}
public Node findNode(String label){
if(this.label.equals(label))
return this;
for(Node child : this.children)
if (child.findNode(label) != null)
return child.findNode(label);
return null;
}
}
i need a method like "Node findNode(String label)" but gives the lowest possible Node with the same label.
Example in this image
Modify your Node.class to store another variable the int height which is derived whilst you traverse your Tree objectTree from the rootNode.
The rootNode.getHeight()=0 by default. Simple traversal from the rootNode function in Node.class will look like the following:
//note : This assumes you are at any Node. The root Node will have height = 0 ~important
public Node findLabel(String label){
Node tempNode = null;
assert this.getHeight()!=null;
if(this.label.equals(label)){
tempNode = this;
}
//traverse this' children
for(Node child : this.children){
child.setHeight(this.getHeight()+1); //setting children height
Node t = child.findNode(label);
if(t!=null){
if(tempNode!=null){
if(tempNode.getHeight()>t.getHeight()){
tempNode=t;
}
}else{
tempNode=t; //set TempNode = t as tempNode is null as this is our first solution
}
}
}
return tempNode; //can be null and Contains the lowest node in the tree with label
}
Try something like this, it's just an idea, i haven't tried it.
You need to count the number of odd nodes you have passed.
public static int max_depth = 0;
public static Node max_Node = null;
public Node findNode(String label){
int counter = 0;
if(this.label.equals(label))
if(max_depth < counter){
max_Node = this;
max_depth = counter;
}
for(Node child : this.children){
if (child.findNode(label) != null){
if (child.findNode(label) != null){
counter++;
Node findNode(String label);
}
}
}
}
after modifying Siddarth Sreeni's answer some more i came up with this answer that seems to be the correct one
here is the code :
import java.util.ArrayList;
public class Node{
public String label;
public ArrayList<Node> children;
private int level;
public Node(String label){
this.level =0;
this.label =label;
this.children = new ArrayList<Node>();
}
public void addChild(String label){
Node child = new Node(label);
child.setLevel(this.getLevel()+1); //setting children level
this.children.add(child);
}
public void addChild(Node child){
child.setLevel(this.getLevel()+1); //setting children level
this.children.add(child);
}
public Node findNode(String label){
if(this.label.equals(label))
return this;
for(Node child : this.children)
if (child.findNode(label) != null)
return child.findNode(label);
return null;
}
//note : This assumes you are at any Node searching for a child node. The root Node will have level = 0 ~important
public Node findDeepNode(String label){
Node tempNode = null;
if(this.label.equals(label)&&this.findNode(label)==null){
tempNode = this;
}
//traverse this' children
for(Node child : this.children){
Node t = child.findNode(label);
if(t!=null){
if(tempNode!=null){
if(tempNode.getLevel()<t.getLevel() && t.findDeepNode(label)==null){
tempNode=t;
}else tempNode=t.findDeepNode(label);
}else{
if(t.findDeepNode(label)==null)
tempNode=t; //set TempNode = t as tempNode is null as this is our first solution
else tempNode=t.findDeepNode(label); //set TempNode = t.findDeepNode(label) as t has a child of the same label to put in tempNode instead
}
}
}
return tempNode; //can be null and Contains the lowest node in the tree with label
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public static void main(String[] args){
Node node=new Node("E");
node.addChild("E-");
node.addChild("T-");
node.addChild("7");
node.findNode("E-").addChild("F");
node.findNode("E-").addChild("T");
node.findNode("T-").addChild("8");
node.findNode("T-").addChild("9");
node.findNode("9").addChild("9");
node.findDeepNode("9").addChild("T");
System.out.println(node.findDeepNode("T").level);
}
}
This image explains the main method used for testing :
public class Node {
private final int vertex;
private final HashSet<Node> nodes;
public Node(int index) {
this.index = index;
this.nodes = new HashSet<Node>();
}
protected void addOutgoingEdge(Node a) {
nodes.add(a);
}
public class DirectedGraph {
private Map<Integer, Node> vertices;
public DirectedGraph(String str) {
this.vertices = new HashMap<Integer, Node>();
str = str.replaceAll("[a\\s\\[]", "");
String[] edges = str.split("]");
for (String edge : edges) {
String[] points = edge.split(",");
int[] integerPoint = new int[2];
integerPoint[1] = Integer.parseInt(points[1]);
Node incoming = new Node(integerPoint[0]);
Node outgoing = new Node(integerPoint[1]);
// Need to construct the map and add edges here
}
}` enter code here`
protected void addEdge(Node origin, Node destination) {
origin.addOutgoingEdge(destination);
}
I am having a bit of some trouble getting the ball rolling on my Directed Graph
I have two classes: A Node class and a DirectedGraph class. The DirectedGraph class will pass in a String to construct a graph. I can't seem to initialize the GraphNode and the respective edges in my DirectedGraph class, however. I know I will be using a Map to get unique keys but the values (outgoing edges) is screwing me up. I know I am very close, I just keep slipping up.
The sample output would be like 1-----> 2 4 -----> 3 5 ------> 4
Where the left column is the vertex and the right column is an outgoing edge. I would appreciate any tips. Here are my classes:
Hi I've coded a solution for you I refactored a little your code, and I focused on the relationship creation:
package com.stackoverflow.graph;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* This class manages the Directed Graph creation, and all the methods related to build a Directed Graph
*
*/
public class DirectedGraph {
Map<Node, List<Node>> graph;
public DirectedGraph() {
this.graph = new HashMap<Node, List<Node>>();
}
void createRelationship(Node input, Node output) {
List<Node> outputs = graph.get(input);
//If is a new node create their output list, (all the nodes to which it has relationship)
if (outputs == null)
outputs = new ArrayList<Node>();
//Check that the node is not in the list, to avoid duplication
if (!outputs.contains(output)){
outputs.add(output);
graph.put(input,outputs);
}
}
void printGraph(){
Iterator it = this.graph.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
List<Node> outputs = (List<Node>) pair.getValue();
for(Node node : outputs){
System.out.print(pair.getKey().toString() + "-->" + node + " ");
}
it.remove(); // avoids a ConcurrentModificationException
}
}
}
------------------
package com.stackoverflow.graph;
public class Node {
//This is the only field you need for your implementation
private Integer value;
public Node(int value){
this.value = value;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
#Override
public String toString() {
return value.toString();
}
}
----------------------
package com.stackoverflow.graph;
public class App {
public static void main(String[] args) {
DirectedGraph graph = new DirectedGraph();
//This is the final result, with your parse you must prepare this code to run in this way:
Node n1 = new Node(1);//Instead of the hardcoded values 1,2,3,4,5 take the parsed ones
Node n2 = new Node(2);
Node n3 = new Node(3);
Node n4 = new Node(4);
Node n5 = new Node(5);
//put this code into a loop to create each edge
graph.createRelationship(n1, n2);
graph.createRelationship(n3, n4);
graph.createRelationship(n3, n5);
//Duplicate relationship but not added
graph.createRelationship(n3, n5);
graph.printGraph();
}
}
Output:
1-->2 3-->4 3-->5
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();
}
}
}
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.
I have a very simple Graph implementation as follows:
class Graph{
ArrayList<Node> nodes;
...
public void addNode(Node n){
nodes.add(n);
}
void changeLabel(int index, char label){
nodes.get(index).label = label;
}
}
class Node{
char label;
ArrayList<Node> connections;
public void addConnection(Node other){
connections.add(other);
}
}
Next, I create a cyclic Graph as follows:
Graph g = new Graph();
Node a = new Node('A');
Node b = new Node('B');
Node c = new Node('C');
//code to add nodes to graph
g.addNode(a);
g.addNode(b);
g.addNode(c);
//code to add each node as connection to every other node
a.addConnection(b);
a.addConnection(c);
b.addConnection(a);
b.addConnection(c);
....
Then, I change the label on one of the graph nodes (say A to E):
g.changeLabel(0, 'E');
Now, when I display the Graph nodes, I can see the updated label. However, when I iterate through the connections of the nodes, I still get the label as 'A'. Why is it so?
I am sure that the problem is not in the snippet of the code that you have posted. The program below works correctly. Try to match it up with yours.
import java.util.List;
import java.util.ArrayList;
public class Temp_1 {
public static void main(String[] args) {
Graph graph = new Graph();
graph.nodes = new ArrayList<Node>();
//add nodes
Node node1 = new Node();
node1.label = 'A';
Node node2 = new Node();
node2.label = 'B';
graph.nodes.add(node1);
graph.nodes.add(node2);
printNodes(graph);
graph.nodes.get(0).addConnection(graph.nodes.get(1));
graph.nodes.get(1).addConnection(graph.nodes.get(0));
printConnections(graph);
graph.changeLabel(0, '1');
System.out.println("after changing label");
printNodes(graph);
printConnections(graph);
}
static void printNodes(Graph g) {
System.out.println("Printing Nodes ");
for (Node elem_ : g.nodes) System.out.println(elem_.label);
}
static void printConnections(Graph g) {
System.out.println("Printing Connections ");
for (Node elem_ : g.nodes) {
System.out.println("Printing Connections for node [" + elem_.label + "]");
for (Node connection_ : elem_.connections) {
System.out.println(connection_.label);
}
}
}
}
class Graph{
public ArrayList<Node> nodes;
void changeLabel(int index, char label){
nodes.get(index).label = label;
}
}
class Node{
char label;
ArrayList<Node> connections = new ArrayList<Node>();
public void addConnection(Node other){
connections.add(other);
}
}