I am trying to create tree linked list in java and print Tree by levels of balls in metric spaces and I am unsuccessful.
create class ball:
public class Ball {
private double Point;
private double Radius;
public Ball(double Point, double Radius) {
this.Point = Point;
this.Radius = Radius;
}
public double getPoint() {
return Point;
}
public double getRadius() {
return Radius;
}
public void setPoint(double p)
{
this.Point=p;
}
public void setRadius(double r)
{
this.Radius=r;
}
public String toString(Ball b)
{
return b.Point+ " " + b.Radius;
}
}
and create class TreeNode
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
public class TreeNode<T> {
T data;
TreeNode<T> parent;
LinkedList<TreeNode<T>> children;
TreeNode next;
public TreeNode(T data ) {
this.data = data;
this.children = new LinkedList<TreeNode<T>>();
this.parent = null;
}
public TreeNode(T data , TreeNode<T> parent)
{
this.data=data;
this.parent=parent;
this.children = new LinkedList<TreeNode<T>>();
}
public TreeNode<T> addChild(T child)
{
TreeNode<T> childNode = new TreeNode<T>(child);
childNode.parent = this;
this.children.add(childNode);
return childNode;
}
public void setNext(TreeNode e)
{
this.next=e;
}
public TreeNode getNext()
{
return this.next;
}
public TreeNode <T> Insert(TreeNode<T> pos, T x)
{
TreeNode <T> tmp = new TreeNode <T>(x);
if(pos == null)
{
tmp.setNext(this.parent);
this.parent= tmp;
}
else{
tmp.setNext(pos.getNext());
}
return tmp;
}
public TreeNode<T> getParent() {
return parent;
}
public T getData() {
return data;
}
public LinkedList<TreeNode<T>> getChild ()
{
return children;
}
public void setData(T data1)
{
this.data=data1;
}
public void setParent(TreeNode<T> getParent)
{
this.parent=parent;
}
public String toString()
{
return this.data.toString() ;
}
}
In addition create class cover tree levels
my problem is insert element to tree
public class CoverTreeLevels {
static final int LEVELS = 25;
public static Data d;
public static void Insert(TreeNode node, TreeNode newNode)
{
newNode.parent=node.parent;
node.parent=newNode.parent;
}
public static void buildTree(double [][] data)
{
double rootRadius =d.Find_Max_Radiues(d.data);
Ball rootBall = new Ball(data[0][0], rootRadius);
TreeNode root = new TreeNode<Ball>(rootBall);
TreeNode last = root;
for (double i = 1, lastRadius = rootRadius / 2; i < LEVELS - 1; i++, lastRadius /= 2) {
Ball ball = new Ball( data[0][0] , lastRadius);
last = last.addChild(ball);
for (int j = 1; j < data.length; j++) {
TreeNode<Ball> n = last;
while (true)
{
if(d.dist(j, 0)> lastRadius)
{
Ball newBall = new Ball(data[j][0], lastRadius);
n.addChild(newBall) ;
}
n.getParent();
}
}
}
}
and class Data which includes data in metric spaces.
Am I headed in the right direction?
For one, it looks like you have some issues with access modifiers in this code.
Here, you're referencing private properties of these objects without using the getters/setters you specified. This will be a compiler error.
Second, your insert method seems to be setting the node.parent to itself.
public static void Insert(TreeNode node, TreeNode newNode)
{
newNode.parent=node.parent; // new node's parent is being set to current node's parent.
node.parent=newNode.parent; // current node's parent being set to newNode's parent, which you just assigned to node.parent above
}
To insert properly, you'd need to insert the newNode itself into the equation:
public static void Insert(TreeNode node, TreeNode newNode)
{
if ( node != null && newNode != null) {
TreeNode temp;
temp = node.getParent(); // get the current node's parent
node.setParent(newNode); // set the new parent of current node to newNode
newNode.setParent(temp); // set the new node's parent to current node's old parent
}
}
Now you should have a properly functioning insert.
Related
I can't write correctly function that deletes one node from tree. If this node has children, they should move one level higher. Children of deleted element will have parent of deleted elem,ancestors will they on they places, but one level higher. How can I do it right?
import java.util.ArrayList;
import java.util.List;
public class Node<T> {
private T value;
private final List<Node<T>> listOfChildren;
private Node<T> parent;
public Node(){
super();
listOfChildren = new ArrayList<>();
}
public Node(T value){
this();
setValue(value);
}
public T getValue() {
return value;
}
public void setParent(Node<T> parent) {
this.parent = parent;
}
public List<Node<T>> getListOfChildren() {
return listOfChildren;
}
public void setValue(T value) {
this.value = value;
}
public int getNumberOfChildren() {
return listOfChildren.size();
}
public void addChildren(Node<T> child) {
parent = this;
listOfChildren.add(child);
}
public void removeChildAt(int index) {
if (index > listOfChildren.size()-1){
throw new IndexOutOfBoundsException( "This index is too big");
}
else {
Node<T> element = this.listOfChildren.get(index);
if (element.listOfChildren.size() > 0) {
// function...
}
listOfChildren.remove(index);
}
}
}
I think that writing dfs or bfs to walk through the tree is not the best way to realize this function. What is the best way to realize this function?
Children of deleted element will keep their descendants, so no walk through required
public void removeChildAt(int index) throws IndexOutOfBoundsException {
if (listOfChildren != null) {
Node<T> element = this.listOfChildren.get(index);
if (element.listOfChildren.size() > 0) {
this.listOfChildren.addAll(element.listOfChildren);
//element.listOfChildren.forEach(child -> child.setParent(this)); but you have no backward reference to parent
}
listOfChildren.remove(index);
}
else {
System.out.println("No children from this node");
}
}
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 wrote this code to create a binary tree but looks like this code is creating an unbalanced binary tree. The nodes are getting only on the right subtree of root. I get Null pointer exception if I try to access child nodes of left subtree. I want to create a balanced binary tree with nodes getting inserted from left to right. What mistake am I doing here and how to rectify it?
public class binTree {
public static class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val){
this.val = val;
this.left = null;
this.right = null;
}
}
public TreeNode root;
public binTree(){
this.root = null;
}
public void insert(int data){
root = insert(root,data);
}
public TreeNode insert(TreeNode node,int data){
if(node == null){
node = new TreeNode(data);
//root = node;
}
else{
if(node.left == null){
node.left = insert(node.left,data);
}
else{
node.right = insert(node.right,data);
}
}
return node;
}
public static void main(String args[]){
binTree obj = new binTree();
obj.insert(5);
obj.insert(11);
obj.insert(13);
obj.insert(1);
obj.insert(7);
obj.insert(21);
obj.insert(35);
System.out.println(obj.root.right.left.val);
System.out.println(obj.root.left.right.val); // this throws null pointer exception
}
}
You'll need to store the quantity of elements for every sub-tree at each tree-node like this:
public class BinTree {
private TreeNode root;
public static class TreeNode {
public int val;
public int elements = 0;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
this.left = null;
this.right = null;
}
}
public BinTree() {
this.root = null;
}
public void insert(int data) {
root = insert(root, data);
}
private static int height(TreeNode node) {
int result = 0;
if (node != null) {
result++;
int total = node.elements;
int heightElements = 2;
while (total > heightElements) {
total -= heightElements;
heightElements *= 2;
result++;
}
}
return result;
}
public TreeNode insert(TreeNode node, int data) {
if (node == null) {
node = new TreeNode(data);
} else if (height(node.left) == height(node.right)) {
node.left = insert(node.left, data);
} else {
node.right = insert(node.right, data);
}
node.elements++;
return node;
}
public static void main(String args[]) {
BinTree obj = new BinTree();
obj.insert(5);
obj.insert(11);
obj.insert(13);
obj.insert(1);
obj.insert(7);
obj.insert(21);
obj.insert(35);
System.out.println(obj.root.val);
System.out.println(obj.root.left.val);
System.out.println(obj.root.right.val);
System.out.println(obj.root.left.left.val);
System.out.println(obj.root.left.right.val);
System.out.println(obj.root.right.left.val);
System.out.println(obj.root.right.right.val);
}
}
I'm trying to implement a Binary Tree in java with Generics, i searched and i find this question: Implementing Binary Tree in Java with Generic Comparable<T> data?, but i couldn't resolve my doubts. So i have two classes,
BST_Tree<T>
and
Node<T extends Comparable<T>>
I want that my implementation can:
Take every type of Object and put it inside the field key in Node
Compare every node with the key field
This is the code:
public class Node < T extends Comparable < T >> {
private T key;
private Node left;
private Node right;
private Node p;
public void setKey(T key) {
this.key = key;
}
public T getKey() {
return key;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
public void setLeft(Node left) {
this.left = left;
}
public void setRight(Node right) {
this.right = right;
}
public void setP(Node p) {
this.p = p;
}
public boolean getBolCompMin(T key) {
return this.key.compareTo(key) < 0;
}
}
My Node class is suppose to extend Comparable in order to compare the key.
This is my tree:
public class BST_Tree < T > {
private ArrayList < Node > nodes;
private Node root;
public BST_Tree(Node root) {
this.root = root;
}
public void insertNode(T key) {
Node z = new Node();
z.setKey(key);
Node x = this.root;
Node y = new Node();
while (x != null) {
y = x;
if (z.getBolCompMin(x.getKey())) {
x = x.getLeft();
} else {
x = x.getRight();
}
}
z.setP(y);
if (z.getBolCompMin(y.getKey())) {
y.setLeft(z);
} else {
y.setRight(z);
}
}
public void InOderWalk(Node x) {
if (x != null) {
InOderWalk(x.getLeft());
System.out.println(x.getKey());
InOderWalk(x.getRight());
}
}
public Node getRoot() {
return root;
}
}
My tree tries to set the key in node z but it fails. This is the error:
incompatible types: T cannot be converted to java.lang.Comparable
Thank you in advance!
Your
public class BST_Tree<T>
should be
public class BST_Tree<T extends Comparable<T>>
And every Node variable inside your BST_Tree and Node classes should be Node<T>.
This would ensure that you can only instantiate your BST_Tree class with element types that implement Comparable.
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);
}