i have a problem calling multiple instance of a class that i have coded (Tree, TreeNode)
in the main method, the system would give the output c d j c d j even though both trees are obviously different trees.
if i were to separate both postOrder() calls(each called after the tree has been pushed in to the stack)
Stack<Tree> alphaStack = new Stack<Tree>();
TreeNode a = new TreeNode('i');
Tree tree = new Tree(a);
TreeNode newleft = new TreeNode('a');
TreeNode newright = new TreeNode('b');
tree.setLeft(a, newleft);
tree.setRight(a, newright);
alphaStack.push(tree);
Tree.postOrder(alphaStack.pop().getRoot());
TreeNode b = new TreeNode('j');
Tree newtree = new Tree(b);
TreeNode left = new TreeNode('c');
TreeNode right = new TreeNode('d');
newtree.setLeft(b, left);
newtree.setRight(b, right);
alphaStack.push(newtree);
Tree.postOrder(alphaStack.pop().getRoot());
the output would be a b i c d j.
Does this mean that my class is not being duplicated but instead being reused when i make new Trees?
Below is the code:
import java.util.Stack;
public class mast_score {
public static void main(String[] args){
Stack<Tree> alphaStack = new Stack<Tree>();
TreeNode a = new TreeNode('i');
Tree tree = new Tree(a);
TreeNode newleft = new TreeNode('a');
TreeNode newright = new TreeNode('b');
tree.setLeft(a, newleft);
tree.setRight(a, newright);
alphaStack.push(tree);
TreeNode b = new TreeNode('j');
Tree newtree = new Tree(b);
TreeNode left = new TreeNode('c');
TreeNode right = new TreeNode('d');
newtree.setLeft(b, left);
newtree.setRight(b, right);
alphaStack.push(newtree);
Tree.postOrder(alphaStack.pop().getRoot());
Tree.postOrder(alphaStack.pop().getRoot());
} }
code for TreeNode
public class TreeNode{
Object item;
TreeNode parent;
TreeNode left;
TreeNode right;
public TreeNode (Object item) {
this.item = item;
parent = null;
left = null;
right = null;
}
public TreeNode getParent(TreeNode current) throws ItemNotFoundException
{
if(current == null) throw new ItemNotFoundException("No parent");
if(current.parent == null) throw new ItemNotFoundException("This
is the root");
else return current.parent;
}
public TreeNode getLeft(TreeNode current) throws ItemNotFoundException
{
if(current == null) throw new ItemNotFoundException("No left or
right child");
if(current.left == null) throw new ItemNotFoundException("No left
child");
else return current.left;
}
public TreeNode getRight(TreeNode current) throws ItemNotFoundException
{
if(current == null) throw new ItemNotFoundException("No left or
right child");
if(current.right == null) throw new ItemNotFoundException("No
right child");
else return current.right;
}
public Object getElement() throws ItemNotFoundException {
if(this.item == null) throw new ItemNotFoundException("No such
node");
else return this.item;
} }
code for Tree class
import java.util.*;
public class Tree {
static TreeNode root;
int size;
public Tree() {
root = null;
}
public Tree(TreeNode root) {
Tree.root = root;
}
public TreeNode getRoot() {
return this.root;
}
public int getLvl(TreeNode node) {
return node.lvlCount;
}
public void setLeft(TreeNode node, TreeNode left) {
node.left = left;
}
public void setRight(TreeNode node, TreeNode right) {
node.right = right;
}
public static void postOrder(TreeNode root) {
if (root != null) {
postOrder(root.left);
postOrder(root.right);
System.out.print(root.item + " ");
} else {
return;
}
}
public static int getSize(TreeNode root) {
if (root != null) {
return 1 + getSize(root.left) +
getSize(root.right);
} else {
return 0;
}
}
public static boolean isEmpty(Tree Tree) {
return Tree.root == null;
} }
Your problem is here, in the Tree class:
static TreeNode root;
You should remove the word static, and replace Tree.root with this.root.
Adding the keyword static causes the variable root to be shared between all instances of Tree in your program, which is not what you want.
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 am tasked with building a BinaryTree that represents Morse Code. It branches left with each dot and right with each dash.
I can not figure out, however, why my method to add a Node does not seem to want to work with a BinaryTree object. IntelliJ says that it "can not resolve method".
I am certain that the BinaryTree is not the issue, because I was given detailed instructions on how to write the class by my instructor. Rather, I suspect that I am perhaps referencing the wrong thing here. I have already verified that the parameters being entered isn't the issue.
public static MorseCodeTree<Character> readMorseCodeTree()
{
MorseCodeTree<Character> morse = new MorseCodeTree<Character>();
Node<Character> newNode = new Node<Character>(null);
morse.addNode(newNode, letter, position);
private Node<Character> addNode(Node<Character> currentNode, char data, String morseCode)
{
if (currentNode == null)
{
currentNode = new Node(null);
}
if (morseCode.charAt(0) == '*')
{
currentNode = addNode(currentNode.left, data, morseCode.substring(1));
}
else if (morseCode.charAt(0) == '-')
{
currentNode = addNode(currentNode.right, data, morseCode.substring(1));
}
else
{
currentNode.data = data;
}
return currentNode;
}
BinaryTree class:
import java.io.Serializable;
import java.util.Scanner;
public class BinaryTree implements Serializable{
//implement Node class
protected static class Node<E> implements Serializable
{
protected E data;
protected Node<E> left;
protected Node<E> right;
public Node (E data)
{
this.data = data;
this.left = null;
this.right = null;
}
public String toString()
{
return data.toString();
}
}
protected Node root;
public BinaryTree()
{
root = null;
}
protected BinaryTree(Node<E> root)
{
this.root = root;
}
public BinaryTree(E data, BinaryTree<E> leftTree, BinaryTree<E> rightTree)
{
root = new Node<E>(data);
if (leftTree != null)
{
root.left = leftTree.root;
}
else
{
root.left = null;
}
if (rightTree != null)
{
root.right = rightTree.root;
}
else
{
root.right = null;
}
}
public BinaryTree<E> getLeftSubtree()
{
if (root != null && root.left != null)
{
return new BinaryTree<E>(root.left);
}
else
{
return null;
}
}
public BinaryTree<E> getRightSubtree()
{
if (root != null && root.right != null)
{
return new BinaryTree<E>(root.right);
}
else
{
return null;
}
}
public boolean isLeaf()
{
return (root.left == null && root.right == null);
}
public String toString()
{
StringBuilder sb = new StringBuilder();
preOrderTraverse(root, 1, sb);
return sb.toString();
}
private void preOrderTraverse(Node<E> node, int depth, StringBuilder sb)
{
for (int i = 1; i < depth; i++)
{
sb.append(" ");
}
if (node == null)
{
sb.append("null\n");
}
else
{
sb.append(node.toString() + "\n");
preOrderTraverse(node.left, depth + 1, sb);
preOrderTraverse(node.right, depth + 1, sb);
}
}
public static BinaryTree<String> readBinaryTree(Scanner scan)
{
String data = scan.next();
if (data.equals("null"))
{
return null;
}
else
{
BinaryTree<String> leftTree = readBinaryTree(scan);
BinaryTree<String> rightTree = readBinaryTree(scan);
return new BinaryTree<String>(data, leftTree, rightTree);
}
}
}
You're declaring the addNode(...) method within readMorseCodeTree(), so it's not in the scope of the class. The latter method should look like this:
public static BinaryTree<Character> readMorseCodeTree()
{
BinaryTree morse = new MorseCodeTree();
Node<Character> newNode = new Node<Character>(null);
morse.addNode(newNode, letter, position);
}
I've got a class Node
class Node{
int val;
Node parent;
Node left;
Node right;
public Node (int val){
this.val = val;
}
}
And I have a few methods:
public class Tree{
public Node root = null;
void insertNodeSorted(Node x, Node tree) {
if (x.val < tree.val) {
if (tree.left == null) {
tree.left = x;
}
else
insertNodeSorted(x, tree.left);
}
else {
if (tree.right == null) {
tree.right = x;
}
else
insertNodeSorted(x, tree.right);
}
} // end insertNodeSorted
void deleteNodeSorted(Node x) {
if (root == null)
return;
else
root = deleteNodeSorted(x, root);
}
Node deleteNodeSorted(Node x, Node tree) {
if (x.val < tree.val)
tree.left = deleteNodeSorted(x, tree.left);
else if (x.val > tree.val)
tree.right = deleteNodeSorted(x, tree.right);
else
tree = replaceNodeSorted(tree);
return tree;
} // end deleteNodeSorted
// Additional Method
Node replaceNodeSorted(Node tree) {
if (tree.right == null)
tree = tree.left;
else if (tree.left == null)
tree = tree.right;
else
tree.right = findReplacement(tree.right, tree);
return tree;
} // end replaceNodeSorted
Node findReplacement(Node tree, Node replace) {
if (tree.left != null)
tree.left = findReplacement(tree.left, replace);
else {
replace.val = tree.val;
tree = tree.right;
}
return tree;
} // end findReplacement
And I'd like to compile the Tree, but I don't know what I exactly I need to write in the main method.
public static void main(String[] args){
Tree t = new Tree();
t.insertNodeSorted();
What do I have to write in the brackets in order to print the Tree? (I know I still have to add System.out.println(val); in the methods..)
You defined a variable holding the root node, so it is not necessary to pass the parameter tree for the method insertNodeSorted. You can use always the root node.
Add a method taking only one parameter.
public void insertNodeSorted(Node x) {
if (root == null) {
root = x;
return;
}
insertNodeSorted(x, root);
}
Define the other method with two parameters as private
private void insertNodeSorted(Node x, Node tree) {
...
}
Now you can insert elements as follow:
Tree t = new Tree();
t.insertNodeSorted(new Node(1));
t.insertNodeSorted(new Node(134));
t.insertNodeSorted(new Node(13));
t.insertNodeSorted(new Node(4));
...
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 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