So I¨m building a small game in which I want a search tree with all the possible moves. I¨m having some difficulties implementing the search tree however. I have managed to build a function that can calculate the move but then I¨m not sure how to build the tree, it should be recursivly. Each node should have a list with all possible moves.
public class Tree {
private Node root;
private int level;
public Tree(int level, Board board) {
this.level = level;
root = new Node(board);
}
public void add(Board board) {
int newLevel = board.numberPlacedDiscs();
if(newLevel>level){
//Add this at a new level.
Node newNode =new Node(board);
newNode.setParent(root);
root = newNode;
}else{
//add at this level.
root.addChild(new Node(board));
}
}
}
public class Tree {
private Node root;
private int level;
public Tree(int level, Board board) {
this.level = level;
root = new Node(board);
}
public void add(Board board) {
int newLevel = board.numberPlacedDiscs();
if(newLevel>level){
//Add this at a new level.
Node newNode =new Node(board);
newNode.setParent(root);
root = newNode;
}else{
//add at this level.
root.addChild(new Node(board));
}
}
}
As you can see I don't know how to add new Nodes. How do I know when to go down a level in the tree and add more nodes? Everytime a new disc is added to the board it should go down one level.
Here is a generic tree in Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TreeTest {
public static void main(String[] args) {
Tree tree = new Tree("root");
tree.root.addChild(new Node("child 1"));
tree.root.addChild(new Node("child 2"));
tree.root.getChild("child 1").addChild("child 1-1");
tree.root.getChild("child 1").addChild("child 1-2");
/*
root
-- child 1
---- child 1-1
---- child 1-2
-- child 2
*/
}
private static class Tree {
private Node root;
Tree(String rootData) {
root = new Node();
root.data = rootData;
root.children = new ArrayList<>();
}
public List<Node> getPathToNode(Node node) {
Node currentNode = node;
List<Node> reversePath = new ArrayList<>();
reversePath.add(node);
while (!(this.root.equals(currentNode))) {
currentNode = currentNode.getParentNode();
reversePath.add(currentNode);
}
Collections.reverse(reversePath);
return reversePath;
}
}
static class Node {
String data;
Node parent;
List<Node> children;
Node() {
data = null;
children = null;
parent = null;
}
Node(String name) {
this.data = name;
this.children = new ArrayList<>();
}
void addChild(String name) {
this.addChild(new Node(name));
}
void addChild(Node child) {
this.children.add(child);
}
void removeChild(Node child) {
this.children.remove(child);
}
public void removeChild(String name) {
this.removeChild(this.getChild(name));
}
public Node getChild(int childIndex) {
return this.children.get(childIndex);
}
Node getChild(String childName) {
for (Node child : this.children) {
if (child.data.equals(childName)) {
return child;
}
}
return null;
}
Node getParentNode() {
return this.parent;
}
}
}
blog post about generic tree data structure in java
Hope it helps
You can use this method to insert a Node into your tree:
private void insertNode(Node root, Node oldNode, Node newNode) {
if(root == null) {
return;
}
if(root == oldNode) {
oldNode.addChild(newNode);
return;
}
for(Node child : root.getChildren()) {
insertNode(child, oldNode, newNode);
}
}
So this method takes three parameters:
root - this is the root node of your tree.
oldNode - the node where you want to insert your newNode.
newNode - this is the node you want to be added to the children of your oldNode.
Node that if you pass a Node that does not exist in your tree, it will not throw any error. But you can modify to do it if you want.
Related
I was working on a program to add nodes to a list, but I seem to be doing something wrong...
My java program has three Classes; Demo, Lista and Node
Class Node:
public class Node {
private int num;
private Node tail;
private Node head;
public Node (int num, Node head, Node tail) {
this.num = num;
this.head = head;
this.tail = tail;
}
}
Class Lista:
public class Lista {
private Node nil;
public Lista () {
nil = null;
}
public void add (int num) {
Node newNode = new Node(num, head, tail);
if (head == null) {
head = newNode;
tail = newNode;
}
}
public void display () {
Node current = head;
while(current != null) {
System.out.print(current.num);
}
}
}
Class Demo:
public class Demo {
public static void main ( String [] args) {
Lista lista = new Lista();
lista.add(3);
lista.add(9);
lista.add(7);
lista.display();
}
}
Demo class is to add the different nodes to the list "lista". Class Node has num, head which is the next one and tail which is the previous one. How can I go about getting Class Lista to be able to use head and tail from Class Node? And if it is possible would this code work when running Demo? What should I change/modify to get this to work?
You may want to modify your code something like this:
EDIT - This is a doubly-linked list implementation.
class Node {
int num;
Node prev;
Node next;
Node(int num) {
this.num = num;
}
Node(int num, Node prev, Node next) {
this.num = num;
this.prev = prev;
this.next = next;
}
void setPrev(Node prev) {
this.prev = prev;
}
void setNext(Node next) {
this.next = next;
}
}
class Lista {
Node root;
Node endNode;
public void add(int num) {
Node n = new Node(num);
if (root == null) {
root = n;
} else {
n.setPrev(endNode);
endNode.setNext(n);
}
endNode = n;
}
public void display() {
Node iterateeNode = root;
while (iterateeNode != null) {
System.out.print(iterateeNode.num + " ");
iterateeNode = iterateeNode.next;
}
}
}
The selected answer is technically not correct. For a (single) Linked List, all your Lista need is a single (head) node. Additionally, the Node class needs a single (next) Node field.
The following is a potential implementation of Node:
public class Node {
private Node next;
private int value;
public Node(int value) {
this.value = value;
}
public boolean hasNext() {
return next != null;
}
public Node next() {
return next;
}
public void add(Node node) {
if (next == null) {
next = node;
} else {
Node temp = next;
while (temp != null) {
temp = temp.next;
}
temp = node;
}
}
#Override
public String toString() {
return String.valueOf(value);
}
}
The add() method will insert the new node in next if it is null. Otherwise, it will traverse the nodes until it finds the tail node (the one where next is null).
The Lista has only the first element in the list (head node).
public class Lista {
private Node head;
public void add(Node node) {
if (head == null) {
head = node;
} else {
Node temp = head;
while (temp.hasNext()) {
temp = temp.next();
}
temp.add(node);
}
}
// Other methods
}
When the add() function in the list is called, it will either add the new node as the head (if the list doesn't have one already) or rely on the already added nodes to figure out where the end of the list is in order to insert the new node.
Lastly, to display the list, just override the toString() method in node and add the "toString" value to a string buffer and send the concatenated string value to the console similar to the the code below.
public void display() {
StringBuilder buff = new StringBuilder("[");
buff.append(head);
if (head != null) {
Node next = head.next();
buff.append(",");
while (next != null) {
buff.append(next);
next = next.next();
buff.append(",");
}
}
buff.append("]");
int idx = buff.lastIndexOf(",");
buff.replace(idx, idx+1, "");
System.out.println(buff.toString());
}
Executing the following displays [3,9,7] as expected.
public class Demo {
public static void main ( String [] args) {
Lista lista = new Lista();
lista.add(new Node(3));
lista.add(new Node(9));
lista.add(new Node(7));
lista.display();
}
}
I am writing a code to practice some linked list example with basics but came across a problem when in linked list class in voidadd method what does it means when I pass the Node variable that is "top" inside the node objects ? does it help it to point the previous data? i have indicated the part that refers to my question
public class Node
{
private int data;
private Node nextNode;
public Node(int dataP , Node nextNodeP)
{
data = dataP;nextNode = nextNodeP;
}
public int getData()
{
return data;
}
public Node getNextNode()
{
return nextNode;
}
public void setData(int newData) //to replace the value of some notes [12| ] --> [120| ]
{
data = newData;
}
public void setNext(Node newNextNode) // pointing to top ---> [120| ] ---> [last | null]
{
nextNode = newNextNode;
}
}
public class LinkedList {
private Node top;
private int size;
public LinkedList() {
top = null;
size = 0;
}
public int getSize() {
return size;
}
public void addNode(int newData) {
Node temp = new Node(newData, top); //question
top = temp; //points to the same
size++;
}
}
Define a node at its own class.
Here is a simple example :
public class LinkedList {
private Node first,last;
private int size ;
//adds node as last. not null safe
public void addNode(Node node) {
if(first == null) {
node.setParent(null);
first = node;
last = node;
}else {
node.setParent(last);
last = node;
}
size++;
}
public Node getFirst() {return first;}
public Node getLast() { return last; }
public int getSize() {return size;}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addNode(new Node(0,null));
list.addNode(new Node(1,null));
list.addNode(new Node(2,null));
list.addNode(new Node(3,null));
Node node = list.getLast();
System.out.println("list has "+ list.size + " nodes:");
while(node != null) {
System.out.println(node);
node = node.getParent();
}
}
}
class Node{
private int data;
private Node parent;
Node(int nodeData, Node parent) {
data = nodeData;
this.parent = parent;
}
public int getData() { return data;}
public void setData(int data) { this.data = data; }
public Node getParent() {return parent; }
public void setParent(Node parent) {this.parent = parent;}
#Override
public String toString() {return "Node "+getData() +" parent:"+ getParent();}
}
I'm trying to make a tree structure based on the linked list. Since linked list can only directly point to the next node(For singly linked list), I would like to modify the concept of the linked list. Is it possible to point at the one node from multiple nodes?
Here is an image in drawing
I think the following would work:
class Node {
Node sibling;
Node child;
Object item;
}
sibling will point to next Node at parallel level, child points to Node on lower level.
See below my implementation:
package treeTest;
public class Node {
private Node left;
private Node right;
private String data;
public Node(String data) {
this.data = data;
left = null;
right = null;
}
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;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
package treeTest;
public class Tree {
private Node root;
public Tree() {
root = null;
}
public void insert(String data) {
root = insert(root, data);
}
private Node insert(Node node, String data) {
if(node == null) {
// Then create tree
node = new Node(data);
} else {
if(data.compareTo(node.getData()) <= 0) {
node.setLeft( insert(node.getLeft(), data));
} else {
node.setRight(insert(node.getRight(), data));
}
}
return node;
}
}
package treeTest;
import java.util.Scanner;
public class TestTree {
public static void main(String[] args) {
// TODO Auto-generated method stub
Tree tree = new Tree();
tree.insert("Hurricane");
// Second level
tree.insert("Cat1");
tree.insert("Cat2");
tree.insert("Cat3");
}
}
For more details checkout this Java Program to Implement a Binary Search Tree using Linked Lists
I wrote the following code to implement the recursive insert method for the BST. But when I print the tree in walk over order it prints the original tree before insertion. It seems as if the element was not inserted. Please help me out. Thanks in advance. Also please suggest the change in code. By the way, the intial tree in walk over order is 2 5 5 6 7 8.
package DataStructures;
class TreeNode {
private TreeNode parent;
private TreeNode childLeft;
private TreeNode childRight;
private int key;
public TreeNode(){
}
public TreeNode(int key) {
this(key, null);
}
public TreeNode(int key, TreeNode parent) {
this(key, parent, null, null);
}
public TreeNode(int key, TreeNode parent, TreeNode childLeft, TreeNode childRight) {
this.key = key;
this.parent = parent;
this.childLeft = childLeft;
this.childRight = childRight;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public TreeNode getChildLeft() {
return childLeft;
}
public void setChildLeft(TreeNode childLeft) {
this.childLeft = childLeft;
}
public TreeNode getChildRight() {
return childRight;
}
public void setChildRight(TreeNode childRight) {
this.childRight = childRight;
}
}
public class BinarySearchTreeBasicTest {
private static class BinarySearchTree {
private TreeNode root;
private TreeNode maxNode = new TreeNode(0);
public BinarySearchTree(TreeNode root) {
this.root = root;
}
public void printTheTreeInOrderWalk(TreeNode x) {
if (x != null) {
printTheTreeInOrderWalk(x.getChildLeft());
System.out.print(x.getKey() + " ");
printTheTreeInOrderWalk(x.getChildRight());
}
}
public void insertNode(TreeNode node, int key){
if (node == null){
node = new TreeNode(key);
}
else{
if (node.getKey() > key){
insertNode(node.getChildLeft(), key);
} else if (node.getKey() < key){
System.out.println("k");
insertNode(node.getChildRight(), key);
} else{
// dont do anything
}
}
}
}
public static void main(String[] args) {
TreeNode rootNode = new TreeNode(6);
BinarySearchTree tree = new BinarySearchTree(rootNode);
TreeNode node1 = new TreeNode(5);
TreeNode node2 = new TreeNode(7);
rootNode.setChildLeft(node1);
rootNode.setChildRight(node2);
node1.setParent(rootNode);
node2.setParent(rootNode);
TreeNode node3 = new TreeNode(2);
TreeNode node4 = new TreeNode(5);
node1.setChildLeft(node3);
node1.setChildRight(node4);
node3.setParent(node1);
node4.setParent(node1);
TreeNode node5 = new TreeNode(8);
node5.setParent(node2);
node2.setChildRight(node5);
tree.insertNode(rootNode, 3);
tree.printTheTreeInOrderWalk(rootNode);
}
}
In your insertNode() method, you are just creating a new node; you are never adding the newly created node to its parent. You should check whether you are going to insert here or not or you should return the newly returned node and set it accordingly.
If you don't want too much deviation from your current program, you can make the following changes.
public void insertNode(TreeNode node, int key) {
if (node.getKey() > key) {
if (node.left == null) { //check if you want to insert the node here
TreeNode newNode = new TreeNode(key);
node.left = newNode;
} else {
insertNode(node.getChildLeft(), key);
}
} else if (node.getKey() < key) {
if(node.right == null){ //check if you want to insert the node here
TreeNode newNode = new TreeNode(key);
node.right = newNode;
} else {
insertNode(node.getChildRight(), key);
}
} else {
// don't do anything
}
}
In Java, parameters are passed by value. In insertNode, if you don't do anything else with the node, the line node = new TreeNode(key); will not do anything useful.
The typical implementation of an insertion in a tree works by returning the TreeNode that will replace the previous one:
private TreeNode insertNode(TreeNode node, int key){
if (node == null){
node = new TreeNode(key);
}
else{
if (node.getKey() > key){
node.setChildLeft(insertNode(node.getChildLeft(), key));
} else if (node.getKey() < key){
node.setChildRight(insertNode(node.getChildRight(), key));
} else{
// dont do anything
}
}
return node;
}
Going a bit further, the previous method should actually be private. The public method should look like this:
public void insertNode(int key){
root = insertNode(root, key);
}
Please someone help!!i m a newbie in Java. i want to make a tree structure from an Array List. My input is
1.1
1.2
1.3
1.3.1.1
1.3.1.2
1.4
1.4.1.1
1.4.2.1
and my aim is to get a Tree like
1.1
1.2
1.3
1.4 1.3.1.1
1.4.1.1 1.5 1.3.1.2
1.4.1.2
and so on.
Please find below my classes for the same. I get a nullPoniter at test.tree.Node.addChild(Node.java:28) and I know it is because the 'children' is null but I dont know how to set the children for the first time. Please Help... :(
public class Tree {
private Node root;
public Tree(String rootData)
{
root=new Node();
root.data=rootData;
root.children=new ArrayList<Node>();
}
public Tree() {
super();
}
public Node getRoot(){
return this.root;
}
public void setRoot(Node rootElement) {
this.root = rootElement;
}
}
and Node class
class Node {
String data;
Node parent;
List<Node> children;
public Node() {
super();
}
public Node(String name)
{
super();
this.data=name;
}
public void addChild(String name) {
this.addChild(new Node(name));
}
public void addChild(Node child) {
this.children.add(child);
}
public void removeChild(Node child) {
this.children.remove(child);
}
public void removeChild(String name) {
this.removeChild(this.getChild(name));
}
public Node getChild(int childIndex) {
return this.children.get(childIndex);
}
public Node getChild(String childName) {
for (Node child : this.children) {
if (child.data.equals(childName)) { return child; }
}
return null;
}
public List<Node> getChildren() {
if (this.children == null) {
return new ArrayList<Node>();
}
return this.children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
public Node getParentNode() {
return this.parent;
}
}
and the Test class is
public class TreeTest {
public static void main(String[] args) {
TreeTest tt = new TreeTest();
ArrayList<String> newArr= new ArrayList<String>();
newArr.add("1.1");
newArr.add("1.2");
newArr.add("1.3");
newArr.add("1.3.1.1");
newArr.add("1.3.1.2");
newArr.add("1.4");
newArr.add("1.4.1.1");
newArr.add("1.4.2.1");
int lCount=0;
int maxCount= newArr.size();
Tree tr= new Tree();
Node rootNode = new Node();
String parent_name=null;
Node currentNode= new Node();
for(String line: newArr){
if(lCount==0){
rootNode = tt.getTree(line);
tr.setRoot(rootNode);
currentNode= rootNode;
}
else{
List<Integer> cur = new ArrayList<Integer>();
List<Integer> pre = new ArrayList<Integer>();
cur= tokenize(line);
pre= tokenize(newArr.get(lCount-1));
if(cur.size()==pre.size()){
currentNode.addChild(tt.getTree(line));
currentNode= tt.getTree(line);
}
else if (cur.size()>pre.size()){
currentNode.addChild(tt.getTree(line));
parent_name= newArr.get(lCount-1);
currentNode= tt.getTree(line);
}
else if(cur.size()< pre.size()){
currentNode= tt.getTree(parent_name);
currentNode.addChild(tt.getTree(line));
currentNode= tt.getTree(line);
}
}
lCount++;
}
}
private Node getTree(String string) {
// TODO Auto-generated method stub
Node rootNode = new Node(string);
return rootNode;
}
private static List<Integer> tokenize(String line) {
// TODO Auto-generated method stub
List<Integer> line_Arr = new ArrayList<Integer>();
String[] tokens = line.split("\\.");
int i=0;
for(String atr: tokens)
line_Arr.add(Integer.parseInt(atr));
return line_Arr;
}
}
In both constructors of your Node class, add this statement after the super call: -
children = new ArrayList<Node>();
This will instantiate your List children.
public Node() {
super();
this.children = new ArrayList<Node>();
}
public Node(String name)
{
super();
this.children = new ArrayList<Node>();
this.data=name;
}
Also, you can change your 1-arg and 0-arg Tree constructor from: -
public Tree(String rootData)
{
root=new Node();
root.data=rootData;
root.children=new ArrayList<Node>();
}
public Tree() {
super();
}
to the below one, that will instantiate the Node using the parameterized constructor: -
public Tree(String rootData) {
root=new Node(rootData);
}
public Tree() {
root = new Node();
}
P.S: -
You don't need to add super() call explicitly, if you only want to invoke the super class 0-arg constructor. Compiler adds this call by default.