I'm working on a school assignment about creating a balanced binary tree. Interfaces for the Node and the Tree were supplied with declared methods. However, the Node interface had only getLeft, getRight and getValue methods, no setters. Since we submit for grading only the implementation files, I worked around it by using the implementation class itself for typing, instead of the Interface.
When I messaged the teacher, he told me it was possible to implement it using merely the Node constructor, adding a "hint" that "For every node, its child are also trees." which is obvious, but I'm not sure how that is to help me.
It seems to me that without using setters, I'd first need to basically map out the tree in advance and then start building it from bottom instead of from top, which seems needlessly complicated and counter-intuitive. Is there some trick I'm missing?
Thank you for any help or advice you can offer.
My current implementations are as follows:
TreeImpl.java
public class TreeImpl implements Tree {
private NodeImpl root;
public TreeImpl() {}
#Override
public void setTree(int[] values) {
this.root = null;
Arrays.sort(values);
recurseSet(values);
}
private void recurseSet(int[] values) {
if (values.length > 0) {
int middleIndex = values.length / 2;
NodeImpl tempNode = new NodeImpl(values[middleIndex]);
insert(tempNode, root, 1);
recurseSet(cutArray(values, 0, middleIndex - 1));
recurseSet(cutArray(values, middleIndex+1, values.length-1));
}
}
private int[] cutArray(int[] array, int begin, int end) {
int length = end-begin+1;
int[] newArray = new int[length];
System.arraycopy(array, begin, newArray, 0, length);
return newArray;
}
private void insert(NodeImpl node, NodeImpl location, int depth) {
if (root == null) {
root = node;
return;
}
if (node.getValue() < location.getValue()) {
/* left branch */
if(location.getLeft() == null) {
node.setDepth(depth);
location.setLeft(node);
} else {
insert(node, location.getLeft(), depth+1);
}
} else {
/* right branch */
if(location.getRight() == null) {
node.setDepth(depth);
location.setRight(node);
} else {
insert(node, location.getRight(), depth+1);
}
}
}
#Override
public Node getRoot() {
return root;
}
private String toString(NodeImpl root) {
String finalString = "";
if (root != null) {
finalString += root;
finalString += toString(root.getLeft());
finalString += toString(root.getRight());
}
return finalString;
}
#Override
public String toString() {
return toString(root);
}
}
NodeImpl.java
public class NodeImpl implements Node {
private int value;
private NodeImpl left;
private NodeImpl right;
private int depth = 0;
public NodeImpl(int value) {
this.value = value;
}
public void setLeft(NodeImpl left) {
this.left = left;
}
public void setRight(NodeImpl right) {
this.right = right;
}
public void setDepth(int depth) {
this.depth = depth;
}
#Override
public NodeImpl getLeft() {
return left;
}
#Override
public NodeImpl getRight() {
return right;
}
#Override
public int getValue() {
try {
return value;
} catch (NullPointerException e) {
System.out.println("Null pointer.");
}
return 0;
}
#Override
public String toString() {
String finalString = "";
for(int i = 0; i < depth; i++) {
finalString += " ";
}
finalString += "- ";
finalString += value;
finalString += "\n";
return finalString;
}
}
I played with your code a little bit and I think I've figured out how to do that:
class NodeImpl implements Node {
private int value;
private Node left;
private Node right;
public NodeImpl(int value, Node left, Node right) {
this.value = value;
this.left = left;
this.right = right;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
public int getValue() {
return value;
}
#Override
public String toString() {
// here you have to put some nice drawing logic.
return (left != null ? left.toString() : "") + "<-" + value + "->" + (right != null ? right.toString() : "");
}
}
class TreeImpl implements Tree {
private Node root;
public void setTree(int[] values) {
Arrays.sort(values);
this.root = recurseSet(values);
}
private Node recurseSet(int[] values) {
if (values.length > 0) {
int middleIndex = values.length / 2;
return new NodeImpl(
values[middleIndex], recurseSet(cutArray(values, 0, middleIndex - 1)),
recurseSet(cutArray(values, middleIndex + 1, values.length - 1))
);
} else {
return null;
}
}
private int[] cutArray(int[] array, int begin, int end) {
int length = end - begin + 1;
int[] newArray = new int[length];
System.arraycopy(array, begin, newArray, 0, length);
return newArray;
}
public Node getRoot() {
return root;
}
}
And you will use your classes like:
public static void main(String[] args) {
final Tree tree = new TreeImpl();
tree.setTree(new int[]{1, 10, 9, 8, 2, 5});
System.out.println(tree.getRoot().toString());
}
You just have to think how to implement NodeImpl.toString() method to draw each node in a nice way :) I hope it will help you.
Related
I'm trying to write a method that can transfer an array into a Binary tree. I know the code is not right, I run it and hope it would show something that I can continue to fix it. But it just kept loading without any error or result. May anyone give me some advice, please!
Here is the BST class:
public class BSTNode {
private String data;
private BSTNode left;
private BSTNode right;
public BSTNode(String data) {
this.data = data;
this.right = null;
this.left = null;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public BSTNode getLeft() {
return left;
}
public void setLeft(BSTNode left) {
this.left = left;
}
public BSTNode getRight() {
return right;
}
public void setRight(BSTNode right) {
this.right = right;
}
}
And my method:
public BSTNode fromArray(String[] array, int start, int end) {
int i = start;
BSTNode root = new BSTNode(array[i]);
BSTNode current = root;
BSTNode parent = null;
while (i <= end) {
if (array[i].compareTo(current.getData()) < 0) {
parent = current;
current.setLeft(current); //Should I put current.setLeft(root) here?
} else {
parent = current;
current.setRight(current);
}
// Create the new node and attach it to the parent node
if (array[i].compareTo(parent.getData()) < 0) {
parent.setLeft(new BSTNode(array[i]));
} else {
parent.setRight(new BSTNode(array[i]));
}
i++;
}
return current;
}
Thank you for your time!
After you've initialized the root, you've already inserted the first element, so you can increment i right away.
You set the left and right pointers without keeping track of the prior value.
You never change the value of current within the loop, and, as you immediately assign it to parent, you don't change parent either.
You should return the root instead of the current node.
How about something like this:
while (++i <= end) {
current = root;
while (current != null) {
parent = current;
if (array[i].compareTo(current.getData()) < 0) {
current = current.getLeft();
} else {
current = current.getRight();
}
}
// Create the new node and attach it to the parent node
if (array[i].compareTo(parent.getData()) < 0) {
parent.setLeft(new BSTNode(array[i]));
} else {
parent.setRight(new BSTNode(array[i]));
}
}
return root;
UPDATE:
You can avoid a redundant comparison by keeping its result in a variable:
while (++i <= end) {
boolean left;
current = root;
do {
parent = current;
left = array[i].compareTo(current.getData()) < 0;
if (left) {
current = current.getLeft();
} else {
current = current.getRight();
}
} while (current != null);
// Create the new node and attach it to the parent node
if (left) {
parent.setLeft(new BSTNode(array[i]));
} else {
parent.setRight(new BSTNode(array[i]));
}
}
return root;
public class Main {
public static final class Node {
public static final String NULL = "_";
public static final String SPLIT = ",";
private final String val;
private Node left;
private Node right;
public Node(String val) {
this.val = val;
}
}
public static void main(String... args) {
Node root = createBinaryTree();
String str = serialize(root); // 0,1,3,7,_,9,_,_,_,4,_,_,2,5,_,8,_,_,6,_,_
Node newRoot = deserialize(str);
}
private static String serialize(Node root) {
StringBuilder buf = new StringBuilder();
serialize(root, buf);
return buf.toString();
}
private static void serialize(Node node, StringBuilder buf) {
if (buf.length() > 0)
buf.append(Node.SPLIT);
if (node == null)
buf.append(Node.NULL);
else {
buf.append(node.val);
serialize(node.left, buf);
serialize(node.right, buf);
}
}
private static Node deserialize(String str) {
String[] values = str.split(Node.SPLIT);
return deserialize(values, new AtomicInteger());
}
private static Node deserialize(String[] values, AtomicInteger i) {
if (i.get() >= values.length)
return null;
String value = values[i.getAndIncrement()];
if (Node.NULL.equalsIgnoreCase(value))
return null;
Node node = new Node(value);
node.left = deserialize(values, i);
node.right = deserialize(values, i);
return node;
}
/*
* 0
* / \
* 1 2
* / \ / \
* 3 4 5 6
* / \
* 7 8
* \
* 9
*/
private static Node createBinaryTree() {
Node[] nodes = { new Node("0"), new Node("1"), new Node("2"), new Node("3"),
new Node("4"), new Node("5"), new Node("6"), new Node("7"),
new Node("8"), new Node("9") };
nodes[0].left = nodes[1];
nodes[0].right = nodes[2];
nodes[1].left = nodes[3];
nodes[1].right = nodes[4];
nodes[2].left = nodes[5];
nodes[2].right = nodes[6];
nodes[3].left = nodes[7];
nodes[5].right = nodes[8];
nodes[7].right = nodes[9];
return nodes[0];
}
}
how can i send (node.data) from SortTree Class to TreePrinter then used to print A Tree .
import javax.swing.tree.TreeNode;
public class SortTree {
static Node root;
TreePrinter type =new TreePrinter();
class Node<A extends Comparable>{
int data;
Node left, right;
Node(int d) {
data = d;
left = null;
right = null;
}
}
Node sortedArrayToBST(int arr[], int start, int end) {
if (start > end) {
return null;
}
int mid = (start + end) / 2;
Node node = new Node(arr[mid]);
node.left = sortedArrayToBST(arr, start, mid - 1);
node.right = sortedArrayToBST(arr, mid + 1, end);
return node;
}
void preOrder(Node node) {
if (node == null) {
return;
}
//System.out.print(node.data + " ");
preOrder(node.left);
preOrder(node.right);
}
}
And this is TreePrinter class :
import java.io.IOException;
import java.io.OutputStreamWriter;
public class TreePrinter {
public static class Node<T extends Comparable<T>> {
T value;
Node<T> left, right;
public void insertToTree(T v) {
if (value == null) {
value = v;
return;
}
if (v.compareTo(value) < 0) {
if (left == null) {
left = new Node<T>();
}
left.insertToTree(v);
} else {
if (right == null) {
right = new Node<T>();
}
right.insertToTree(v);
}
}
public void printTree(OutputStreamWriter out) throws IOException {
if (right != null) {
right.printTree(out, true, "");
}
printNodeValue(out);
if (left != null) {
left.printTree(out, false, "");
}
}
private void printNodeValue(OutputStreamWriter out) throws IOException {
if (value == null) {
out.write("<null>");
} else {
out.write(value.toString());
}
out.write('\n');
}
private void printTree(OutputStreamWriter out, boolean isRight, String indent) throws IOException {
if (right != null) {
right.printTree(out, true, indent + (isRight ? " " : " | "));
}
out.write(indent);
if (isRight) {
out.write("┌");
} else {
out.write("└");
}
out.write("────");
printNodeValue(out);
if (left != null) {
left.printTree(out, false, indent + (isRight ? " | " : " "));
}
}}}
nodes sorted as preorder any help to send (node.data) to treeprinter class then type the tree:
I recommend you implement a toString, rather than this TreePrinter.
I've slightly changed your Node class, moved it outside the SortTree, resulting in the code available from https://github.com/johanwitters/stackoverflow-tree-printer.
The implementation of Node is here:
package com.johanw.stackoverflow.tree;
import com.johanw.stackoverflow.util.Helper;
public class Node<A extends Comparable>{
private static int AMOUNT_INDENT = 3;
private int data;
private Node left, right;
public Node(int d) {
data = d;
left = null;
right = null;
}
public void setLeft(Node left) {
this.left = left;
}
public void setRight(Node right) {
this.right = right;
}
public int getData() {
return data;
}
public Node getLeft() {
return left;
}
public Node getRight() {
return right;
}
public void indent(StringBuilder builder, int indent) {
builder.append(Helper.repeat(indent * (AMOUNT_INDENT + 1), " "));
}
public void newLine(StringBuilder builder) {
builder.append(System.lineSeparator());
}
public String toString(int indent) {
StringBuilder builder = new StringBuilder();
builder.append(data);
newLine(builder);
if (left != null) {
indent(builder, indent);
builder.append("└" + Helper.repeat(AMOUNT_INDENT, "─") + left.toString(indent + 1));
}
if (right != null) {
indent(builder, indent);
builder.append("└" + Helper.repeat(AMOUNT_INDENT, "─") + right.toString(indent + 1));
}
return builder.toString();
}
#Override
public String toString() {
return toString(0);
}
}
The below unit test gives the bottom output for the given tree structure:
public class TestSortTree {
#Test
public void test() {
Node node = new Node(1);
Node left = new Node(2);
Node leftLeft = new Node(22);
Node leftRight = new Node(23);
Node leftRightLeft = new Node(24);
left.setLeft(leftLeft);
leftRight.setLeft(new Node(39));
left.setRight(leftRight);
node.setLeft(left);
node.setRight(new Node(3));
System.out.println(node.toString());
}
}
I hope this helps
In order to be able to receive the node.data in TreePrinter. I would add the following code
class TreePrinter<T extends Comparable<T>>{
Node<T extends Comparable<T>> root;
public TreePrinter(){
root = new Node<T extends Comparable<T>>();
}
public void insertToTree(T v) {
root.insertToTree(v);
}
It will now be easy printing the tree using the algorithm from this post:
How to print binary tree diagram?
I would send the data by making the following modification to Node sortedArrayToBST(int arr[], int start, int end) in SortTree
void sortedArrayToBST(int arr[], int start, int end) {
if (start > end) {
return;
}
int mid = (start + end) / 2;
type.insertToTree(arr[mid]);
node.left = sortedArrayToBST(arr, start, mid - 1);
node.right = sortedArrayToBST(arr, mid + 1, end);
}
I have not tried running this so might need some debugging, but I think the underlying idea is solid. Hope this helps!
I have a superclass called Tree and a subclass called AVLTree that extends the class Tree.
A tree has children that are also Tree typed. An AVLTree has children that are AVLTree. I want to use the methods i wrote on the Tree class, on this case the getLeft(returns the left son) and setLeft(set the left son).
The problem is the compiler can't convert a Tree to an AVLTree, even though they have the same variables, structure and constructors.
Any ideas on how should I solve this? Or should I just write all the methods that just an AVLTree has on the Tree class?
The code:
Tree.java:
public class Tree<T extends Tree<T>> {
private T left = null;
private T right = null;
private Object data = null;
public Tree () {
//nothing
}
public Tree (Object data, T left, T right) {
this.data = data;
this.left = left;
this.right = right;
}
public Tree (Object data) {
this.data = data;
}
//Get Values
public T getLeft() {
return this.left;
}
public T getRight() {
return this.right;
}
public Object getData() {
return this.data;
}
//Set Values
public void setLeft(T left) {
this.left = left;
}
public void setRight(T right) {
this.right = right;
}
public void setData(Object data) {
this.data = data;
}
public T treeFromText(String in) {
if (in=="()") return null;
int i=0;
T result = null;
//Find expression
int d = in.indexOf('c')+1;
if (d==0) return null;
int begl, endl, begr, endr;
begl = d+1;
endl = ClosingParentesis(in,begl);
endr = in.length()-2;
begr = OpeningParentesis(in,endr);
T left = null, right = null;
if (begl-endl==0) {
left = null;
} else left = treeFromText(in.substring(begl,endl+1));
if (begr-endr==0) {
right = null;
} else right = treeFromText(in.substring(begr,endr+1));
result.setData(in.charAt(d));
result.setLeft(left);
result.setRight(right);
return result;
}
public static int ClosingParentesis(String in, int openPos) {
int closePos = openPos;
int counter = 1;
while (counter > 0 && closePos < in.length()-1) {
closePos++;
if (in.charAt(closePos)=='(') counter++;
if (in.charAt(closePos)==')') counter--;
}
return closePos;
}
public static int OpeningParentesis(String in, int closePos) {
int openPos = closePos;
int counter = 1;
while (counter > 0 && openPos > 0) {
openPos--;
if (in.charAt(openPos)=='(') counter--;
if (in.charAt(openPos)==')') counter++;
}
return openPos;
}
AVLTree.java:
public class AVLTree extends Tree<AVLTree> {
/*
//Values and Variables
private AVLTree left = null;
private AVLTree right = null;
private Object data;
//Inicialization
public AVLTree (Object data, AVLTree left, AVLTree right) {
super(data,left,right);
}
public AVLTree (Object data) {
super(data);
}
*/
public int getfactor() {
return getHeight(this.getLeft())-getHeight(this.getRight());
}
}
Test.java:
public static void main(String[] args) {
AVLTree tree = new AVLTree();
Scanner console = new Scanner(System.in);
String in = console.nextLine().toLowerCase();
tree = (AVLTree) tree.treeFromText(in); //The error is here.
System.out.println(tree.getHeight());
System.out.println(tree.TreePreOrder());
}
The way I expect it to work is that if the String 'in' in the Test.java is "(c3()(c2()()))" the return must be an Tree with value 3 and a right son with value 2. This return must be of type Tree or anything that extends Tree.
You need a way to get an AVLTree instantiated from a String, using the logic in Tree.treeFromText.
Declare Tree as abstract.
Create a new method in Tree:
abstract protected T createEmptyTree();
Override that method in AVLTree to return an empty instance of AVLTree.
#Override
protected AVLTree createEmptyTree() {
return new AVLTree();
}
In treeFromText(), wherever you need to create an empty instance of T, invoke createEmptyTree().
You already have the rest of the logic.
Try to avoid returning null anywhere. It's best to return an empty AVLTree instead of a null.
You can achieve this by the power of generics: define a new circular generic T:
public class Tree<T extends Tree<T>>
{
T left;
T right;
public T doSomething()
{
return left;
}
public static class AVLTree extends Tree<AVLTree>
{
public AVLTree foo()
{
return doSomething();
}
}
}
UPDATE: here is how you can create different tree instances:
import java.util.Objects;
public class TreesFactory
{
public static AVLTree createAVLTreeFrom(String in)
{
return treeFromText(in, AVLTree::new);
}
#FunctionalInterface
interface SimpleFactory<T extends Tree<T>>
{
T createNew();
}
public static <T extends Tree<T>> T treeFromText(String in, SimpleFactory<T> treeFactory)
{
if (Objects.equals(in, "()"))
return null;
T result = treeFactory.createNew();
//Find expression
int d = in.indexOf('c') + 1;
if (d == 0)
return null;
int begl, endl, begr, endr;
begl = d + 1;
endl = ClosingParentesis(in, begl);
endr = in.length() - 2;
begr = OpeningParentesis(in, endr);
T left, right;
if (begl - endl == 0)
{
left = null;
}
else
left = treeFromText(in.substring(begl, endl + 1), treeFactory);
if (begr - endr == 0)
{
right = null;
}
else
right = treeFromText(in.substring(begr, endr + 1), treeFactory);
result.setData(in.charAt(d));
result.setLeft(left);
result.setRight(right);
return result;
}
public static int ClosingParentesis(String in, int openPos)
{
int closePos = openPos;
int counter = 1;
while (counter > 0 && closePos < in.length() - 1)
{
closePos++;
if (in.charAt(closePos) == '(')
counter++;
if (in.charAt(closePos) == ')')
counter--;
}
return closePos;
}
public static int OpeningParentesis(String in, int closePos)
{
int openPos = closePos;
int counter = 1;
while (counter > 0 && openPos > 0)
{
openPos--;
if (in.charAt(openPos) == '(')
counter--;
if (in.charAt(openPos) == ')')
counter++;
}
return openPos;
}
}
And the Main:
public static void main(String[] args)
{
Scanner console = new Scanner(System.in);
String in = console.nextLine().toLowerCase();
AVLTree tree = TreesFactory.createAVLTreeFrom(in);
//...
}
I have already put in the following methods for a binary search tree:
import java.util.Collections;
import java.util.NoSuchElementException;
import java.util.ArrayList;
public class MyTree {
private class Node
{
public String data;
public int data2;
public Node left;
public Node right;
public Node(String data, Node left, Node right)
{
this.data = data;
this.left = left;
this.right = right;
}
}
private static Node root = null;
private int getHeight(Node subroot)
{
if (subroot == null)
return -1;
int maxLeft = getHeight(subroot.left);
int maxRight = getHeight(subroot.right);
return Math.max(maxLeft, maxRight) + 1;
}
public String toString()
{
return toString(this.root);
}
private String toString(Node subroot)
{
if (subroot==null)
return "";
return toString(subroot.left)+subroot.data+toString(subroot.right);
}
public boolean containsRecursive(String value)
{
return contains(value, this.root);
}
private boolean contains(String value, Node subroot)
{
if (subroot==null)
return false;
else if (value.equals(subroot.data))
return true;
else if (value.compareTo(subroot.data) < 0)
return contains(value, subroot.left);
else
return contains(value, subroot.right);
}
public boolean contains(String value) // not recursive
{
Node subroot = this.root;
while (subroot != null)
{
if (value.equals(subroot.data))
return true;
else if (value.compareTo(subroot.data) < 0)
subroot = subroot.left;
else
subroot = subroot.right;
}
return false;
}
public int addUp()
{
return addUp(this.root);
}
private int addUp(Node subroot)
{
if (subroot==null)
return 0;
return addUp(subroot.left)+subroot.data2+addUp(subroot.right);
} //data = String, data2 = int
public int count()
{
return count(this.root);
}
private int count(Node subroot)
{
if (subroot==null)
return 0;
return count(subroot.left)+1+count(subroot.right);
}
public int numberLess(int x)
{
return numberLess(this.root, x);
}
private int numberLess(Node subroot, int x)
{
if (subroot==null)
return 0;
if (x < subroot.data2)
return numberLess(subroot.left, x)+1+numberLess(subroot.right, x);
return numberLess(subroot.left, x)+numberLess(subroot.right, x);
}
public int findMax()
{
return findMax(this.root);
}
private int findMax(Node subroot) throws NoSuchElementException
{
if (subroot==null)
throw new NoSuchElementException();
return Math.max(findMax(subroot.left), findMax(subroot.right));
}
private ArrayList<Integer> addToList(Node subroot, ArrayList<Integer> a)
{
if (subroot!=null){
a.add(subroot.data2);
addToList(subroot.left, a).addAll(addToList(subroot.right, a));
return a;
}
return new ArrayList<Integer>();
}
private ArrayList<Integer> getSortedList(){
ArrayList<Integer> rawList = addToList(this.root, new ArrayList<Integer>());
Collections.sort(rawList);
return rawList;
}
public void rebalance(){
ArrayList<Integer> list = getSortedList();
}
}
How can I finish the rebalance method using the structure I already have? I'd like to use the sorted arraylist by finding the midpoints and recursively ordering them. I'm not sure how this would be approached using the way I have my tree set up (with the internal node class) so I'd like some help with this code.
Split the array in two equal sized portions. Take the median element as new root node.
Then split again the two portions and take the median element as second level nodes, etc.
Best implemented recursively....
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.