I did a code that take as input integers, for example: 123 11 200 1 100 150 2000 and need to output a binary tree, in this form:
┌1
┌11┤
│ └100
123┤
│ ┌150
└200┤
└2000
but in my code output is:
0┐
│ ┌1
│ ┌11┤
│ │ └100
└123┤
│ ┌150
└200┤
└2000
At he root appear a zero and I do not know why.
This is my code. I consider that the problem is in the add() method, but do not know how to solve it. I will be grateful for help.
public class TreeNode extends BinaryTree implements PrintableTree {
private int i;
private TreeNode leftChild;
private TreeNode rightChild;
public TreeNode(int i) {
this.i = i;
}
public TreeNode() {
}
#Override
public void add(int i) {
if (i > this.i) {
if (this.rightChild == null) {
this.rightChild = new TreeNode(i);
} else {
this.rightChild.add(i);
}
} else {
if (this.leftChild == null) {
this.leftChild = new TreeNode(i);
} else {
this.leftChild.add(i);
}
}
}
public int getI() {
return i;
}
public void setLeftChild(TreeNode leftChild) {
this.leftChild = leftChild;
}
public void setRightChild(TreeNode rightChild) {
this.rightChild = rightChild;
}
public TreeNode getLeftChild() {
return leftChild;
}
public TreeNode getRightChild() {
return rightChild;
}
#Override
public String prettyPrint() {
StringBuilderPlus builder = new StringBuilderPlus();
prettyPrint(builder, "", "", "", "");
return builder.toString();
}
public void print() {
StringBuilderPlus res = new StringBuilderPlus();
prettyPrint(res, "", "", "", "");
}
public void prettyPrint(StringBuilderPlus result, String prefix, String left, String mid, String right) {
String indent = " ".repeat(String.valueOf(i).length());
if (leftChild != null) {
leftChild.prettyPrint(result, prefix + left + indent, " ", "┌", "│");
}
result.appendLine(prefix + mid + i
+ " ┐┘┤".charAt((leftChild != null ? 2 : 0)
+ (rightChild != null ? 1 : 0)));
if (rightChild != null) {
rightChild.prettyPrint(result, prefix + right + indent, "│", "└", " ");
}
}
}
public class StringBuilderPlus {
private StringBuilder sb;
public StringBuilderPlus(){
sb = new StringBuilder();
}
public void append(String str)
{
sb.append(str != null ? str : "");
}
public void appendLine(String str)
{
sb.append(str != null ? str : "").append(System.getProperty("line.separator"));
}
public String toString()
{
return sb.toString();
}
}
class BinaryTree {
private TreeNode root;
public void Print() {
if (root != null) {
root.print();
}
}
public void add(int i) {
if (root == null) {
root = new TreeNode(i);
} else {
root.add(i);
}
}
}
public interface PrintableTree {
void add(int i);
String prettyPrint();
static PrintableTree getInstance() {
return new TreeNode();
}
}
Thank you for posting the rest of the code. Your issue is with the PrintableTree interface in method getInstance. You return a new TreeNode (it comes initialized with 0 as int is a primitive type and cannot be null). And then you add the rest of the nodes to that original node with 0. You most likely wanted to return a new BinaryTree instead. However you need to change your code as BinaryTree does not implement the PrintableTree interface.
Here are the changes necessary to fix it:
In PrintableTree.java
static PrintableTree getInstance() {
return new BinaryTree();
}
In BinaryTree.java
// notice the added implements
class BinaryTree implements PrintableTree {
// the rest of the class is fine, add this to the end
#Override
public String prettyPrint() {
if (root != null) {
return root.prettyPrint();
}
return "";
}
}
Also the class TreeNode does not need to extend BinaryTree as a node is not a tree (it doesn't make sense for the node the contain a value AND a root). If your assignment requires this relation then edit the code accordingly.
Related
I was about to build a binary tree, I didn't use the Generic because the static method can't invoke it so I planned to use the Object class to replace it. In that way, I could enter any type of value like int or String as I want.
But unfortunately, here it is, it is an error.
I put the code below, and pls help with this. I appreciate it.
import java.util.*;
public class MainFunction {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3};
BinaryTree bt = createBTree(arr,0);//this is where the error is ,(The method createBTree(int[], int) is undefined for the type MainFunction)
}
}
public class BinaryTree
{
private Object val;
private BinaryTree leftBTree;
private BinaryTree rightBTree;
public BinaryTree(Object val)
{
this.val = val;
}
private void clearTree()
{
this.val = null;
this.leftBTree = null;
this.rightBTree = null;
}
public void addRightTree (BinaryTree tree)
{
rightBTree = tree;
}
public void addLeftTree (BinaryTree tree)
{
leftBTree = tree;
}
public void editTree(Object val)
{
this.val = val;
}
public boolean isEmpty(BinaryTree tree)
{
if(tree != null)
return false;
return true;
}
public void deleteTree(BinaryTree tree)
{
tree.clearTree();
if(tree.leftBTree != null)deleteTree(tree.leftBTree);
if(tree.rightBTree != null)deleteTree(tree.rightBTree);
}
public static BinaryTree createBTree(Object[] arr,int index)
{
BinaryTree tree = null;
if(index<arr.length&&arr[index] != null)
{
tree = new BinaryTree(arr[index]);
tree.leftBTree = createBTree(arr,index*2+1);
tree.rightBTree = createBTree(arr,index*2+2);
}
return tree;
}
public void preOrderTraversal(BinaryTree tree)
{
System.out.println(tree.val);
if(tree.leftBTree != null)
preOrderTraversal(tree.leftBTree);
if(tree.rightBTree != null)
preOrderTraversal(tree.rightBTree);
}
public void inOrderTraversal(BinaryTree tree)
{
if(tree.leftBTree != null)
inOrderTraversal(tree.leftBTree);
System.out.println(tree.val);
if(tree.rightBTree != null)
inOrderTraversal(tree.rightBTree);
}
public void postOrderTraversal(BinaryTree tree)
{
if(tree.leftBTree != null)
postOrderTraversal(tree.leftBTree);
if(tree.rightBTree != null)
postOrderTraversal(tree.rightBTree);
System.out.println(tree.val);
}
}
First of all, I didn't get why you can't use generics - with static method, you just make method static, too.
Secondly, int[] is NOT Object[] - because primitives in java are not objects, hence your code is not working.
Here's the fixed code with generics that works (note it uses Integer instead of int):
public class BinaryTree<T> {
private T val;
private BinaryTree<T> leftBTree;
private BinaryTree<T> rightBTree;
public BinaryTree(T val) {
this.val = val;
}
private void clearTree() {
this.val = null;
this.leftBTree = null;
this.rightBTree = null;
}
public void addRightTree(BinaryTree<T> tree) {
rightBTree = tree;
}
public void addLeftTree(BinaryTree<T> tree) {
leftBTree = tree;
}
public void editTree(T val) {
this.val = val;
}
public boolean isEmpty(BinaryTree<T> tree) {
return tree == null;
}
public void deleteTree(BinaryTree<T> tree) {
tree.clearTree();
if (tree.leftBTree != null) deleteTree(tree.leftBTree);
if (tree.rightBTree != null) deleteTree(tree.rightBTree);
}
public static <T> BinaryTree<T> createBTree(T[] arr, int index) {
BinaryTree<T> tree = null;
if (index < arr.length && arr[index] != null) {
tree = new BinaryTree<>(arr[index]);
tree.leftBTree = createBTree(arr, index * 2 + 1);
tree.rightBTree = createBTree(arr, index * 2 + 2);
}
return tree;
}
public void preOrderTraversal(BinaryTree<T> tree) {
System.out.println(tree.val);
if (tree.leftBTree != null)
preOrderTraversal(tree.leftBTree);
if (tree.rightBTree != null)
preOrderTraversal(tree.rightBTree);
}
public void inOrderTraversal(BinaryTree<T> tree) {
if (tree.leftBTree != null)
inOrderTraversal(tree.leftBTree);
System.out.println(tree.val);
if (tree.rightBTree != null)
inOrderTraversal(tree.rightBTree);
}
public void postOrderTraversal(BinaryTree<T> tree) {
if (tree.leftBTree != null)
postOrderTraversal(tree.leftBTree);
if (tree.rightBTree != null)
postOrderTraversal(tree.rightBTree);
System.out.println(tree.val);
}
public static void main(String[] args) {
Integer[] arr = new Integer[]{1, 2, 3};
BinaryTree<Integer> bt = createBTree(arr, 0);
}
}
I've just created a method to test the height of my binary tree implementation as follows:
public int height() {
return height(rootNode);
}
private int height(BinaryTreeNode node) {
if(node == null) return -1;
else return 1 + Math.max(height(node.getLeftChild()), height(node.getRightChild()));
}
But it returns a height of 6, and not 7 when i add the nodes 1-6.
Here is my Binary Tree code:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
public class BinaryTree<E extends Comparable<E>>
{
private class BinaryTreeNode
{
private E value;
private BinaryTreeNode leftChild, rightChild;
public BinaryTreeNode(E value) {
this(value, null, null);
}
public BinaryTreeNode(E value, BinaryTreeNode leftChild, BinaryTreeNode rightChild) {
this.value = value;
this.leftChild = leftChild;
this.rightChild = rightChild;
}
public E getValue() {
return value;
}
public BinaryTreeNode getLeftChild() {
return leftChild;
}
public BinaryTreeNode getRightChild() {
return rightChild;
}
public void setLeftChild(BinaryTreeNode newLeftChild) {
this.leftChild = newLeftChild;
}
public void setRightChild(BinaryTreeNode newRightChild) {
this.rightChild = newRightChild;
}
}
private BinaryTreeNode rootNode;
public BinaryTree() {
this.rootNode = null;
}
public void addNode(E value) {
if(rootNode == null)
rootNode = new BinaryTreeNode(value);
else
addNode(value, rootNode);
}
//TODO: Implement removeNode()
public void printLevelOrder() {
printLevelOrder(rootNode);
}
public int height() {
return height(rootNode);
}
public void inOrderTraversal() {
if(rootNode != null) inOrderTraversal(rootNode);
else System.out.println("The tree is empty!");
}
private void addNode(E value, BinaryTreeNode node) {
if(node.getValue().compareTo(value) > 0) {
if(node.getLeftChild() != null)
addNode(value, node.getLeftChild());
else
node.setLeftChild(new BinaryTreeNode(value));
} else {
if(node.getRightChild() != null)
addNode(value, node.getRightChild());
else
node.setRightChild(new BinaryTreeNode(value));
}
}
private void printLevelOrder(BinaryTreeNode node) {
Queue<BinaryTreeNode> currentLevel = new LinkedList<BinaryTreeNode>();
Queue<BinaryTreeNode> nextLevel = new LinkedList<BinaryTreeNode>();
currentLevel.add(node);
while (!currentLevel.isEmpty()) {
Iterator<BinaryTreeNode> iter = currentLevel.iterator();
while (iter.hasNext()) {
BinaryTreeNode currentNode = iter.next();
if (currentNode.leftChild != null) {
nextLevel.add(currentNode.leftChild);
}
if (currentNode.rightChild != null) {
nextLevel.add(currentNode.rightChild);
}
System.out.print(currentNode.value + " ");
}
System.out.println();
currentLevel = nextLevel;
nextLevel = new LinkedList<BinaryTreeNode>();
}
}
private int height(BinaryTreeNode node) {
if(node == null) return -1;
else return 1 + Math.max(height(node.getLeftChild()), height(node.getRightChild()));
}
private void inOrderTraversal(BinaryTreeNode node) {
if(node != null) {
inOrderTraversal(node.leftChild);
System.out.println(node.getValue() + " ");
inOrderTraversal(node.getRightChild());
}
}
public BinaryTreeNode getRoot() {
return rootNode;
}
}
I think the problem is adding my node into the tree, but I've taken a look at other examples but they all seem to be doing the same thing I am.. So i can't realise the problem!
Thanks!
private int height(BinaryTreeNode node) {
if(node == null) return 0;
else return 1 + Math.max(height(node.getLeftChild()), height(node.getRightChild()));
}
You were returning -1 on node==null when you should return 0.
The condition is true when we arrive to leaf so for example if we add 1-2 then we have height as 1+Max(leftof(1),rightof(1))=
1+Max(height(null),height(2))=
1+Max(0,1+Max(leftof(2),rightof(2)))=
1+Max(0,1+Max(height(null),height(null)))=
1+Max(0,1+Max(0,0))=
1+Max(0,1+0)=
1+1=2.
Try to replace height(null) with -1 in the previous example to see by yourself.
By the way your BinaryTree implementation is actually a binary search tree since you're putting less elements on the left and bigger elements on the right, If a search tree is your intention then Ok but if you want to implement a general binary tree then you should change the add function.
I'm trying to write code in a way that it is object oriented. In this particular case I want to keep track of the minimum value of my stack in O(1) time. I know how to do it, the idea of it, well my idea of it, which is to have another stack that keeps track of the minimum value for every push and pop.
I've nested every class inside of the program class which is called minStack, which doesn't seem like the right thing to do however when I create a instance of minStack and call its variables it works out fine for a regular stack. I created a class that extends a Stack called StackWithMin but I don't know how to call its values. Should I create a new instance of a StackWithMin? If so how would i do it? I did it at the end of the code above the main function, but peek() always returns null
class minStack {
public class Stack {
Node top;
Object min = null;
Object pop() {
if(top != null) {
Object item = top.getData();
top = top.getNext();
return item;
}
return null;
}
void push(Object item) {
if(min == null) {
min = item;
}
if((int)item < (int)min) {
min = item;
}
Node pushed = new Node(item, top);
top = pushed;
}
Object peek() {
if(top == null) {
//System.out.println("Its null or stack is empty");
return null;
}
return top.getData();
}
Object minimumValue() {
if(min == null) {
return null;
}
return (int)min;
}
}
public class Node {
Object data;
Node next;
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public void setNext(Node n) {
next = n;
}
public Node getNext() {
return next;
}
public void setData(Object d) {
data = d;
}
public Object getData() {
return data;
}
}
public class StackWithMin extends Stack {
Stack s2;
public StackWithMin() {
s2 = new Stack();
}
public void push(Object value) {
if((int)value <= (int)min()) {
s2.push(value);
}
super.push(value);
}
public Object pop() {
Object value = super.pop();
if((int)value == (int)min()) {
s2.pop();
}
return value;
}
public Object min() {
if(s2.top == null) {
return null;
}
else {
return s2.peek();
}
}
}
Stack testStack = new Stack();
StackWithMin stackMin = new StackWithMin();
public static void main(String[] args) {
minStack mStack = new minStack();
//StackWithMin stackMin = new StackWithMin();
mStack.testStack.push(3);
mStack.testStack.push(5);
mStack.testStack.push(2);
mStack.stackMin.push(2);
mStack.stackMin.push(4);
mStack.stackMin.push(1);
System.out.println(mStack.testStack.peek());
System.out.println(mStack.stackMin.peek());
mStack.testStack.pop();
}
}
I would suggest to create generic interface Stack like this one
interface Stack<T> {
void push(T item);
T pop();
T peek();
}
Generics add stability to your code by making more of your bugs
detectable at compile time.
See more about generics here.
Then implement this interface in a common way. All implementation details will be hidden inside of this class (your Node class for example). Here is the code (it is just to show the idea, if you want to use it you need to improve it with exception handling for example). Note that class Node is now also generic.
class SimpleStack<T> implements Stack<T> {
private class Node<T> { ... }
private Node<T> root = null;
public void push(T item) {
if (root == null) {
root = new Node<T>(item);
} else {
Node<T> node = new Node<T>(item, root);
root = node;
}
}
public T pop() {
if (root != null) {
T data = root.getData();
root = root.getNext();
return data;
} else {
return null;
}
}
public T peek() {
if (root != null) {
return root.getData();
} else {
return null;
}
}
}
Now we get to the part with stored minimum value. We can extend our SimpleStack class and add field with another SimpleStack. However I think this is better to make another implementation of the Stack and store two stacks for values and for minimums. The example is below. I have generalize the class that now uses Comparator to compare object, so you can use any other object types.
class StackWithComparator<T> implements Stack<T> {
private Comparator<T> comparator;
private SimpleStack<T> mins = new SimpleStack<>();
private SimpleStack<T> data = new SimpleStack<>();
public StackWithComparator(Comparator<T> comparator) {
this.comparator = comparator;
}
public void push(T item) {
data.push(item);
if (mins.peek() == null || comparator.compare(mins.peek(), item) >= 0) {
mins.push(item);
} else {
mins.push(mins.peek());
}
}
public T pop() {
mins.pop();
return data.pop();
}
public T peek() {
return data.peek();
}
public T min() {
return mins.peek();
}
}
Now you can use both implementations like so
SimpleStack<Integer> s1 = new SimpleStack<>();
s1.push(1);
s1.push(2);
s1.push(3);
System.out.println(s1.pop()); // print 3
System.out.println(s1.pop()); // print 2
System.out.println(s1.pop()); // print 1
StackWithComparator<Integer> s2 = new StackWithComparator<>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
});
s2.push(1);
s2.push(2);
s2.push(3);
s2.push(0);
s2.push(4);
System.out.println(s2.min() + " " + s2.pop()); // print 0 4
System.out.println(s2.min() + " " + s2.pop()); // print 0 0
System.out.println(s2.min() + " " + s2.pop()); // print 1 3
System.out.println(s2.min() + " " + s2.pop()); // print 1 2
System.out.println(s2.min() + " " + s2.pop()); // print 1 1
I am trying to figure out how to print a first-child next sibling tree. What I want is the following:
root
|
firstChild - sibling - sibling
|
child - sibling - sibling
I have the following code to add childs and siblings :
class Program
{
static void Main(string[] args)
{
GeneralTree<string> tree = new GeneralTree<string>();
tree.root = new TreeNode<string>
{
Data = "Root"
};
TreeNode<string> child = tree.addChild(tree.root, "Child");
tree.addSibling(child, "Sibling");
tree.print(tree.root);
}
}
class GeneralTree<T>
{
public TreeNode<T> root;
public TreeNode<T> addChild(TreeNode<T> parent, T data)
{
parent.FirstChild = new TreeNode<T>
{
Data = data,
NextSibling = parent.FirstChild
};
return parent.FirstChild;
}
public TreeNode<T> addSibling(TreeNode<T> sibling, T data)
{
sibling.NextSibling = new TreeNode<T>
{
Data = data,
FirstChild = sibling.NextSibling
};
return sibling.NextSibling;
}
int count = 0;
public void print(TreeNode<T> Node)
{
if(Node !=null)
{
Console.WriteLine(Node.Data);
print(Node.FirstChild);
++count;
Console.WriteLine(count);
print(Node.NextSibling);
}
}
}
class TreeNode<T>
{
public T Data { get; set; }
public TreeNode<T> FirstChild { get; set; }
public TreeNode<T> NextSibling { get; set; }
}
Does anyone now how to print that out?
Thanks in advance!
I choosed to merge TreeNode and GeneralTree in this way :
public class TreeNode<T>
{
public T data;
public List<TreeNode<T>> childs;
public TreeNode<T> firstChild()
{return childs.get(0);}
public void appendChild(TreeNode<T> child)
{childs.add(child);}
public void print() {/* ... */}
/* ... */
public static void main(String args[])
{ /* ... */}
}
Then, a way to write print() recursively :
public void print()
{
print(0);
}
public void print(int offset)
{
if (node == null) return; // nothing to print anymore
System.out.println(this.data); // printing the root data
TreeNode<T> lastChild=null;
String output = "";
for(Iterator<TreeNode<T>> i = childs.iterator(); i.hasNext(); )
{
lastChild = i.next();
if (output != "") output += " - ";
output += lastChild.data;
}
// length will be the next line offset
// (size of the current line output minus last item length
int length = output.length()-lastChild.toString().length;
// use a repeat() string function like this one :
output = org.apache.commons.lang.StringUtils.repeat(" ", length) + (length>0?"|":"") + output;
System.out.println (output);
lastChild.print(length);
}
}
Unfortunately I can't validate my code right now, If you have issues, please let me know.
I'm adding values from an ArrayList of Strings to a BST and I'm coming up with a null pointer error on my line "tree.add(s);" and after tracing my code I can't figure out why this is happening. Can someone please help:
public class BinaryTree {
public Node root;
public BinaryTree tree;
private static class Node {
Node left;
Node right;
String data;
Node(String s) {
left = null;
right = null;
data = s;
}
}
public BinaryTree plantTree(ArrayList<String> dict) {
Collections.shuffle(dict);
for (String s : dict) {
s.toUpperCase();
System.out.print(s);
tree.add(s);
}
System.out.print(tree);
System.out.println();
return tree;
}
/**
* Creates an empty binary tree
*/
public BinaryTree() {
root = null;
}
public boolean search(String data) {
return (search(root, data));
}
private boolean search(Node node, String data) {
if (node == null) {
return (false);
}
if (data == node.data) {
return (true);
} else if (data.compareTo(node.data) > 0) {
return (search(node.left, data));
} else {
return (search(node.right, data));
}
}
public void add(String data) {
root = add(root, data);
}
private Node add(Node node, String data) {
if (node == null) {
node = new Node(data);
} else {
if (data.compareTo(node.data) > 0) {
node.left = add(node.left, data);
} else {
node.right = add(node.right, data);
}
}
return (node);
}
}
You have to set the tree variable to something before using it. For example:
public BinaryTree plantTree(ArrayList<String> dict) {
tree = new BinaryTree(); // important!
Collections.shuffle(dict);
for (String s : dict) {
s.toUpperCase();
System.out.print(s);
tree.add(s);
}
System.out.print(tree);
System.out.println();
return tree;
}
Maybe tree should be a local variable of the method rather than an instance variable?