Why is it outputting null for parent and childs!? The logic seems fine to me...
It shouldn't be printing out null for the left, right, and parent since they are updated with left = left.toString(); etc.
The main method:
public class TreeInfo
{
public static void main(String[] args)
{
BinaryTree<Integer> left = new BinaryTree<Integer>(5);
System.out.println(left);
BinaryTree<Integer> right = new BinaryTree<Integer>(9);
BinaryTree<Integer> parent = new BinaryTree<Integer>(1);
BinaryTree<Integer> a = new BinaryTree<Integer>(parent, 5, left, right);
System.out.println(a);
}
}
.
The methods class:
import java.math.*;
import java.lang.*;
import java.util.*;
public class BinaryTree<E> implements BinaryTreeNode<E>
{
protected E data;
protected BinaryTreeNode<E> parent;
protected BinaryTreeNode<E> left;
protected BinaryTreeNode<E> right;
public BinaryTree(BinaryTree<E> parent, E data, BinaryTree<E> left, BinaryTree<E> right)
{
this.data = data;
this.left = left;
this.right = right;
}
public BinaryTree(E data)
{
this(null, data, null, null);
}
public E getData()
{
return this.data;
}
public BinaryTreeNode<E> getParent()
{
return this.parent;
}
public boolean isEmpty()
{
return data == null;
}
public boolean isLeaf()
{
return left == null && right == null;
}
public boolean hasLeft()
{
return left != null;
}
public boolean hasRight()
{
return right != null;
}
public int getNONodes()
{
int count = 1;
if (hasLeft())
{
count += left.getNONodes();
}
if (hasRight())
{
count += right.getNONodes();
}
return count;
}
public String toString() {
if (isLeaf()) {
return data.toString();
}
else {
String root = "null", parent = "null", left = "null", right = "null";
root = data.toString();
if (left != null) {
left = left.toString();
}
if (right != null) {
right = right.toString();
}
if (parent != null)
{
parent = parent.toString();
}
return root + " (" + parent + ", " + left + ", " + right + ")";
}
}
}
inferface:
public interface BinaryTreeNode<E>
{
E getData(); // Returns a reference to data and a reference to its left and right subtrees.
BinaryTreeNode<E> getParent(); // Returns the parent of this node, or null if this node is a root.
boolean isEmpty(); // returns false if the tree is non-empty and true if it is.
boolean hasLeft();
boolean hasRight();
boolean isLeaf();
int getNONodes(); // returns total number of nodes in the Binary Tree.
String toString();
}
output when ran:
5
5 (null, null, null)
Process completed.
In your toString method you're not referencing the left, right and parent objects as class member fields but as the String local variables declared in the method. Use this.left instead:
if(this.left != null) {
left = this.left.toString();
}
In your constructor:
public BinaryTree(BinaryTree<E> parent, E data, BinaryTree<E> left, BinaryTree<E> right)
{
this.data = data;
this.left = left;
this.right = right;
}
You aren't doing anything with the parent. therefore you end up with small trees that aren't connected.
you need to add the line:
public BinaryTree(BinaryTree<E> parent, E data, BinaryTree<E> left, BinaryTree<E> right)
{
this.data = data;
this.left = left;
this.right = right;
this.parent = parent;
}
Related
I want to merge a tree with another tree, t. If there is overlapping data, I want to add them together. This is my code right now. I don't understand how to do this merge function with only parameter t. Doesn't merge usually have two parameters?
public class TreeFunctions {
private TreeNode root;
public TreeFunctions(TreeNode root) {
this.root = root;
}
public TreeNode merge(TreeNode t) {
TreeNode curr = this.root;
if (curr == null) {
return t;
}
if (t == null) {
return curr;
}
curr.data += t.data;
curr.left = merge(t.left);
curr.right = merge(t.right);
return curr;
}
}
public class TreeNode{
TreeNode left;
TreeNode right;
int data;
public TreeNode(int data) {
this.data = data;
}
public TreeNode(int data, TreeNode left, TreeNode right) {
this.data = data;
this.left = left;
this.right = right;
}
public static String inOrder(TreeNode a) {
if(a == null) return "";
else return inOrder(a.left).trim() + " " + a.data + " " + inOrder(a.right).trim();
}
}
EDIT
My tests for merge:
public void testMerge2() {
TreeFunctions c = new TreeFunctions(new TreeNode(5, new TreeNode(2), null));
TreeNode d = new TreeNode(2, new TreeNode(2), new TreeNode(1));
TreeNode res2 = c.merge(d);
assertEquals(TreeNode.inOrder(res2).trim(), "4 7 1");
}
public void testMerge3() {
TreeFunctions c = new TreeFunctions(new TreeNode(5, new TreeNode(2), null));
TreeNode res2 = c.merge(null);
assertEquals(TreeNode.inOrder(res2).trim(), "2 5");
}
public void testMerge4() {
TreeFunctions c = new TreeFunctions(new TreeNode(1, new TreeNode(2, new TreeNode(5), null), null));
TreeNode res2 = c.merge(new TreeNode(1, null, new TreeNode(2, null, new TreeNode(5))));
assertEquals(TreeNode.inOrder(res2).trim(), "5 2 2 2 5");
}
I've edited my answer per your responses. I believe this is what you want.Please try it and let me know.
In the code, function goes down one level for both t1 and t2 so that merge always takes place on the same level and the same side (left-left/right-right).
public TreeNode merge(TreeNode t) {
TreeNode curr = this.root;
merge2(curr,t);
return curr;
}
public void merge2(TreeNode t1,TreeNode t2) {
if(t2==null)
return;
t1.data += t2.data;
if(t2.left!=null)
{
if(t1.left==null)
t1.left = new TreeNode(0);
merge2(t1.left,t2.left);
}
if(t2.right!=null)
{
if(t1.right==null)
t1.right = new TreeNode(0);
merge2(t1.right,t2.right);
}
}
I'm trying to create binary tree by following example 1 where tree is made without getters and setters. I would like to create it with geeters and setters but I'm stuck on line with recursion. How can I call recursion function with/inside setter? Here is the code..
p.s. Tree class pastebin
public class TreeF {
Tree root;
public void insert(int value) {
if (root==null) {
root = new Tree(value);
return;
}
Tree current = root;
if (value < current.getData() ) {
if (current.getLeft()==null) {
current.setLeft(new Tree (value));
}else {
// call insert method inside current.left object [currrent.left(insert(value))]
current=current.getLeft();
insert (value);
}
}
else {
if (current.getRight()==null) {
current.setRight(new Tree (value));
}else {
current=current.getRight();
insert (value);
}
}
}
}
Change insert(value) to current.insert(value)
To implement recursion, you need to change a parameter(or multiple) so you can go to the stopping condition after some recursive calls.
In your code, you called the method insert that was part of the same object. And not its left/right subtree. In other words, the recursion never ends, because you don't visit the child subtrees.
public class Tree {
private int data;
private Tree left;
private Tree right;
public Tree (int data) {
this.data=data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Tree getLeft() {
return left;
}
public void setLeft(Tree left) {
this.left = left;
}
public Tree getRight() {
return right;
}
public void setRight(Tree right) {
this.right = right;
}
public void insert(int value) {
if (value < getData()) {
if (getLeft() == null) {
setLeft(new Tree(value));
} else {
getLeft().insert(value);
}
} else {
if (getRight() == null) {
setRight(new Tree(value));
} else {
getLeft().insert(value);
}
}
}
}
You do not need a current field or a root. Here's your insert method greatly simplified to demonstrate.
public class Tree {
final int data;
Tree left;
Tree right;
public Tree(int value) {
data = value;
}
public void insert(int value) {
if (value < data) {
if (left == null) {
left = new Tree(value);
} else {
left.insert(value);
}
} else {
if (right == null) {
right = new Tree(value);
} else {
right.insert(value);
}
}
}
}
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 am trying to find the mirror image of a binary tree. Here is what I do so far:
import treetoolbox.*;
public class MirrorTree extends BinaryTree<String> {
public MirrorTree(String key) {
this(null, key, null);
}
public MirrorTree(MirrorTree left, String key, MirrorTree right) {
this.key = key;
this.left = left;
this.right = right;
root = this;
}
public MirrorTree mirrorSymmetricTree() {
if (root == null) {
return null;
}
final MirrorTree left = (MirrorTree) root.left;
right = root.right;
root.left = mirrorSymmetricTree(right);
root.right = mirrorSymmetricTree(left);
return (MirrorTree) root;
}
public static MirrorTree mirrorSymmetricTree(BinaryTree<String> t) {
return null;
}
}
What am I doing wrong? The problem should be in this part:
if (root == null) {
return null;
}
final MirrorTree left = (MirrorTree) root.left;
right = root.right;
root.left = mirrorSymmetricTree(right);
root.right = mirrorSymmetricTree(left);
return (MirrorTree) root;
But I think I am missing something.
Delete this function:
public static MirrorTree mirrorSymmetricTree(BinaryTree<String> t) {
return null;
}
Add the parameter to this function to make it recursive:
public MirrorTree mirrorSymmetricTree(BinaryTree<String> t) {
if (root == null) {
return null;
}
final MirrorTree left = (MirrorTree) root.left;
right = root.right;
root.left = mirrorSymmetricTree(right);
root.right = mirrorSymmetricTree(left);
return (MirrorTree) root;
}
Your problem is here:
public static MirrorTree mirrorSymmetricTree(BinaryTree<String> t) {
return null;
}
you are not doing anything in this method!
Assuming you are using a BinaryTree<E> similiar to this documentation
You can see live version of my solution
This is how BinaryTree<E> is built where BinaryTree<E> is the Binary-Tree node itself, and every node in the tree is a tree by itself. This is how the insert method for BinaryTree<E> looks like
public void insert(T value)
{
if (this.value == null)
{
this.value = value;
return;
}
else
{
if (this.value.compareTo(value) >= 0)
{
if (this.left == null)
this.left = new BinaryTree<T>(value);
else
this.left.add(value);
}
else
{
if (this.right == null)
this.right = new BinaryTree<T>(value);
else
this.right.add(value);
}
}
}
Here is how the recursive function look like
private void mirrorSymmetricTree(MirrorTreeNode<T> m, BinaryTreeNode<T> n)
{
if (n == null) // base case
{
return;
}
if (n.left != null)
{
m.left = new MirrorTreeNode<T>(n.left.value);
mirrorSymmetricTree(m.left, n.left);
}
if (n.right != null)
{
m.right = new MirrorTreeNode<T>(n.right.value);
mirrorSymmetricTree(m.right, n.right);
}
}
public static MirrorTree mirrorSymmetricTree(BinaryTree<T> t)
{
if (t == null)
{
return null;
}
if (t.root != null)
{
this.root = new MirrorTreeNode<T>(t.root.value);
mirrorSymmetricTree(this.root, t.root);
}
return this;
}
Where your MirrorTree node would look like this
class MirrorTreeNode<T extends Comparable<T>>
{
public T value;
public MirrorTreeNode<T> left;
public MirrorTreeNode<T> right;
public MirrorTreeNode<T> (T value)
{
this.value = value;
this.left = null;
this.right = null;
}
..
}
Then you can mirror a tree by calling mirrorSymmetricTree on a BinaryTree
BinaryTree<String> t1 = new BinaryTree<>();
t1.addAll({"D","B","F","A","C","E","G"});
// D
// B F
// A C E G
t1.printDFS();
// A, B, C, D, E, F, G
MirrorTree<String> t2 = new MirrorTree<>();
t2.mirrorSymmetricTree(t1);
// t2 is a copy of t1 now
t2.printDFS();
// A, B, C, D, E, F, G
Notes
In order to mirror a binary tree of size N, you have to visit every node in that tree once, thus mirroring a tree has time complexity of O(N)
In order to mirror a binary tree, the items you store has to be Comparable, meaning they can be compared to find out if this.value > input or this.value < input to decide where to put it in the tree
In order to make sure the items are Comparable, you either implement this manually, or you demand that template type has to implement Comparable<T> interface, which force T to have compareTo function that let you compare values\keys as if they were numbers, where A.compareTo(B) > 0 is equivlant to A > B
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.