Binary Tree Creation - java

I am attempting to create a binary tree from an input of 0's and 1's. For example if the input is 11010010 then the tree that is outputted would have 1 as the root. 2 would be the left child of 1 and 4 would be the right child. 2 would have a right child and it would be 3. That is the end of the tree. As the tree is traversed in preorder, the numbers 1-n (n being the number of 1's in the input) are assigned to the nodes that are visited. A 1 means that the root has children. For example the first 1 means that the root is visited and a 1 is placed as the root. The second 1 means that the root has a left child and a 2 is placed there. The 0 after that means it does not have a left child. The next 1 means that it does have a right child and the 3 is placed there, etc. I am confused on how this tree is created. I understand traversing a tree after it has been created but not how to create a tree by traversing it. Any help would be appreciated.
package tree;
import java.io.*;
public class BinaryTree<ArrayList> implements Serializable
{
private static final long serialVersionUID = 1L;
protected static class Node<ArrayList> implements Serializable
{
private static final long serialVersionUID = 1L;
protected int data;
protected Node<ArrayList> left;
protected Node<ArrayList> right;
public Node(int data)
{
this.data = data;
left = null;
right = null;
}
public boolean isLeft()
{
return (left == null);
}
}
protected Node<ArrayList> root;;
public BinaryTree(int x)
{
Node<ArrayList> node = new Node<ArrayList>(x);
this.root = node;
}
public boolean isLeft()
{
return(root.left == null);
}
public void addLeft(int m, BinaryTree.Node<ArrayList> node)
{
root = new Node<ArrayList>(m);
node.left = root;
}
public void preorder(Node<ArrayList> temp)
{
if (temp!=null)
{
System.out.println(temp.data);
preorder(temp.left);
preorder(temp.right);
}
else
return;
}
}

It sounds like you're constructing a tree in a default, breadth-first manner, assigning values to each node based off of what the string says.
If it helps, first turn the string into an ArrayList<int> of values to put in nodes - For example, 11010010 would become {1, 2, 4, 7}, the indices of each set 1 in the string.
Now, we have to construct the tree - but we'll always construct the tree in the exact same way, called breadth first because you fill shallow levels completely before going deep. We make a node, then tell it 'make your left node, then make your right node, then tell your left node to do this, then tell your right node to do this'. (This is as opposed to depth first, where you make your left node, tell your left node to make nodes, then make your right node and tell your right node to make nodes)
So you'd have a recursive method something like this pseudocode:
void continueTree(ArrayList<int> numbers)
{
if (numbers.count() == 0) return;
this.left = new Node(numbers.get(0));
numbers.remove(0);
if (numbers.count() == 0) return;
this.right = new Node(numbers.get(0));
numbers.remove(0);
this.left.continueTree(numbers);
this.right.continueTree(numbers);
}

Related

Create a full and complete binary tree recursively

Purpose:
I would like to create a full and complete binary tree, which saves a String value in its leaves, recursively.
Example 1:
Let's say you want to save two Strings in your tree. So you will need a root and two leaves.
* <- root node
/ \
v0 v1 <- leaves
Example 2:
Let's say you want to save three Strings in your tree. So you will need a root, two inner Nodes but four leaves, so the tree is still complete.
* <- root node
/ \
+ + <- inner node
/ \
/ \
/ \ / \
v0 v1 v2 v3 <- leaves
Math trickery:
Its fairly straightforward to calculate the specs for the binary tree.
Height: ⌈log2 expectedNumOfStrings⌉
double height = Math.log(expectedNumOfStrings) / Math.log(2);
int roundedHeight = (int) Math.ceil(height);
Number of leaves: 2Height
int numOfLeaves = (int) Math.pow(2, roundedHeight);
Number of inner Nodes: 2h − 1
int numOfInnerNodes = (int) (Math.pow(2, roundedHeight)-1)
Implementation:
Let's implement a couple of classes for this binary tree. We'll need a BinaryTree class.
/**
* Create a complete binary tree recursively depending on the expected leaves.
*/
public class BinaryTree {
private InnerNode root;
private LeafNode current;
public BinaryTree(int expectedNumOfStrings) {
//sets root node
this.root = new InnerNode();
//set inner nodes
root.createInnerNodes(expectedNumOfStrings);
//set leaves
root.createLeaves(expectedNumOfStrings);
//The way things are now the tree isn't created in one go.
//I'll have to traverse it again for the leaves.
}
}
All elements of the tree share a link to the parent (for the root it's null). Let's create a class TreeNode:
public class TreeNode {
private TreeNode parent;
}
Now let's create InnerNode and LeafNode which just extends TreeNode.
public class InnerNode extends TreeNode {
private BinaryTree left;
private BinaryTree right;
//used to set the root node
public InnerNode() {
super.parent = null;
this.left=null;
this.right=null;
}
public InnerNode(InnerNode parent) {
super.parent= parent;
}
public TreeNode createInnerNodes(int expectedValues) {
//recursive magic happens here. But how?
}
}
and
public class LeafNode extends TreeNode {
private String data;
public LeafNode(InnerNode parent) {
super.parent= parent;
}
public LeafNode createLeaves(int numOfLeaves) {
//recursive magic happens here again. But how?
}
}
Questions and Problems
I want to keep the classes as separated as they are and I want to set the Tree up in one go. How to I set up InnerNodes and Leaves at the "same" time?
InnerNode left and InnerNode right are private so I can only access them from within InnerNode. But how do I deal with the leaves then? Can I just pass the root Node though to InnerNode/Leaves in a method?
What is best used for the recursion? Height or Number of corresponding nodes? Or something else entirely?
How do you set the left and right pointer? I mean the objects to which they point don't exist yet, do they?
Am I on the right track? /o\

Create a binary tree from a sorted array list

I need to program a Huffman compression for Text for an university assignment.
The exercise is split in to multiple points, and one of them is to create a binary tree from a given sorted arrayList which is of type TreeNode, this class looks like this (I removed the method boddies):
public class TreeNode implements Comparable<TreeNode>, Serializable {
private byte value;
private int frequency;
private TreeNode left, right;
/** Creates new TreeNode .. must get initialized with value */
public TreeNode(byte value) {
this(value, 0, null, null);
}
/** Creates new TreeNode with full init */
public TreeNode(byte value, int frequency, TreeNode left, TreeNode right) {
this.value = value;
this.frequency = frequency;
this.left = left;
this.right = right;
public void incFrequency()
public int getFreq()
public Byte getValue()
public TreeNode getLeft()
public TreeNode getRight()
public boolean isLeaf()
public int getSubTreeSize()
public void toHeap(byte[] heap, int myIndex)
public void initLookup(long myCode, int myDepth, Map<Byte, BitCode> lookupTable)
#Override
public int compareTo(TreeNode o)
#Override
public String toString()
public void printSubTree(PrintStream out, int tabs)
public void write(BitStream bs)
public static TreeNode read(BitStream bs)
}
I need to create a binary tree from an arrayList of type TreeNode, the arrayList is sorted by value so I can assume that the element with the smalles value is at index position 0.
The tree has to fulfill one important condition:
The element with the next bigger value needs to be appended on the left, and the element with an even bigger value needs to be appended to the right (the tree will be builded always to the right).
My attemp to approach this problem was to iterate over the list, getting the item, and then appending each item with an odd index to the left leave of the previous node and each item with an even index to the right leave.
Is there a more elegant way to approach this?
(I dont ask you to do the homework for me, but I could need some ideas)
EDIT:
I need to keep the SortedList, since it is a part of the exercise specification
Only for the sake of helping you, you could think along the following lines:
select the middle element as the root node
split the array list into two - left starting from 0 to mid-1, and right starting from mid+1 to last
Recursively repeat step 1 till there is only one element left in the array.
Return that element when only one is left.
Editing my answer as i didn't understand the requirements properly initially.
First Edit -
You could do something like this -
0. If no element, return
1. make first element your root.
2. make next element if it exists as the left child.
3. recursively call the function making its result the right child.
I finally, after some headache, found a solution to this problem.
I iterated over the List of TreeNode,
I removed the first item from the list and stored it in a tempoary variable called "left", I did the same thing again and called that "right" since the list is sorted this will always deliver the biggest and 2nd biggest (in terms of frequency) element of the list.
I added a new TreeNode to the tree, which has as value 0, as frequency the sum of the frequency of the left and left and right TreeNode and a left and right the left and right which were removed from the list in step 2.
I sorted the list again.
These steps where repeated as long as the tree has a size of more than 1 element.
My code looks like this:
private void initializeTree(List tree) {
do{
TreeNode left = tree.remove(0);
TreeNode right = tree.remove(0);
tree.add(new TreeNode((byte)0, left.getFreq() + right.getFreq(), left, right));
Collections.sort(tree);
}while(tree.size() > 1);
root = tree.get(0);
printTree(System.out);
}
The method print tree is a static method if this class which justs prints the tree to the console, the root variable is the root node of the binary tree.

Implementation of DFS using iterative approach in java

I have seen a lot of implementations of DFS using a boolean variable named visited, which I don't wish to use in my code. While considering a scene where we have a Node class that holds the reference to left and right nodes corresponding to its children and data which can be any Object, can this method be applicable to Binary Trees to calculate dfs ? I have a scenario where I don't have a adjacency list or matrix.
Is the following code a good implementation of DFS ? Is the time complexity of the code O(n) ?
public void dfsForTree(BSTNode root) {
Stack<BSTNode> s = new Stack<BSTNode>();
BSTNode node;
if (root == null) {
return;
}
s.push(root);
while (!s.isEmpty()) {
node = s.pop();
System.out.println(node.getData());
if (node != null) {
if (node.getRight() != null) {
s.push(node.getRight);
}
if (node.getLeft != null) {
s.push(node.getLeft);
}
}
}
}
BSTNode class implementation:
public class BSTNode {
private BSTNode left;
private BSTNode right;
private int data;
/* Constructor */
public BSTNode(int n) {
left = null;
right = null;
data = n;
}
/* Function to set left node */
public void setLeft(BSTNode n) {
left = n;
}
/* Function to set right node */
public void setRight(BSTNode n) {
right = n;
}
/* Function to get left node */
public BSTNode getLeft() {
return left;
}
/* Function to get right node */
public BSTNode getRight() {
return right;
}
/* Function to set data to node */
public void setData(int d) {
data = d;
}
/* Function to get data from node */
public int getData() {
return data;
}
A sure tell of an iterative tree walk is it requires an "up" link on a node (or saves them) to be able to backtrack. You do just this - only saving not "up" links but directly next links to go after backtracking. On the other hand, there are no interdependencies between steps. See Is this function recursive even though it doesn't call itself? for how to distinguish iterative and disguised recursive.
Also see Iterative tree walking for an overview of the algorithms.
Now, for computational complexity. The principle can be found at Big O, how do you calculate/approximate it?.
You do:
process every node
exactly once
push & pop nodes from the stack
each node is also pushed and popped exactly once
So, indeed, it's O(N).

JAVA: Problems creating a Binary Tree

Ok, here is my code. I am trying to practice with Binary Trees. Why can't my size() method access the root node of my binary tree?
Also my root.left, and root.right assignments do not work.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.lang.*;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
System.out.println(bTree.size());
}
}
//Building Binary Trees
class bTree {
static class Node { //remember to initilize a root
String value;
Node left, right;
Node root = new Node("ROOT");
Node lefty = new Node("LEFT0");
Node righty = new Node("RIGHT0");
root.left = lefty;
root.right = righty;
Node(String value, Node left, Node right) {
this.value = value;
this.left = left;
this.right = right;
}
Node(String value) //THIS IS A SIBLING CONSTRUCTOR
{
this(value, null, null);
}
}
public static int size() //Public | sibling constructor
{
System.out.println("Debug0");
System.out.println(root.value);
return size(root);
}
//This method will find the size of a node
private static int size(Node r) //using recursion
{
if (r == null) {
return 0;
} else {
return 1 + (size(r.left) + size(r.right));
}
}
}
Any help would be much appreciated, I have a final tomorrow on this information!
Sam
As your comment in your code says:
//remember to initialize a root
You didn't do that (at least in your sample).
The only variable root is defined in the sub-class of bTree, and is not directly available to the size() method.
size() should read:
public static int size() {
System.out.println("Debug0");
System.out.println(Node.root.value);
return size(Node.root);
}
root is scoped to your static Node class. size() is outside of that scope, so it can't access root.
Something like this would work:
public class TreeTraversal {
class Node {
String value;
Node left, right;
public Node(String value) {
this.value = value;
}
}
public static void main(String[] args) {
// Construct a binary tree
Node root = new Node("root");
Node child = new Node("child 1");
root.left = child;
child = new Node("child 2");
root.right = child;
// Find its size
System.out.println(size(root));
}
private static int size(Node root) {
return sizeRec(root);
}
private static int sizeRec(Node r) {
if (r == null) {
return 0;
} else {
return 1 + (sizeRec(r.left) + sizeRec(r.right));
}
}
}
This is a sort of condensed version of a binary tree. I have attempted to strip away all unnecessary stuff (nested classes, extra imports, static methods except for main, nested static classes, recursive object construction).
public class Node {
private String value;
private Node left;
private Node right;
public Node(String value, Node left, Node right) {
this.value = value;
this.left = left;
this.right = right;
}
public int size() {
int ret = 1;
if (left != null) ret += left.size();
if (right != null) ret += right.size();
return ret;
}
public static void main(String args[]) {
Node tree = new Node("root",
new Node("left", null, null),
new Node("right", null, null));
// expect 3
System.out.println(tree.size());
}
}
Now, notice a few things:
A tree is just a Node.
size is an instance method of Node. (my recursive structure is a bit different than if it were static, in particular, where the null checks go)
The only members of Node are value, left, and right. I don't actually use value for anything, and without an accessor, would have some difficulty doing so.
My assignment to left and right is in the constructor, not floating freely in the class declaration.
Start with something simple.
From here, you could declare a class BTree (But why? is it just to practice having nested classes?). It would contain a Node named root and a size method that simply calls root's size method.
You could declare a nice constructor that doesn't require children. Then you might also want to provide methods on a Node to set the children after construction.
Relax and focus on the specific problems that are going to be on your final. Find a different practice problem and try again. Eat healthy and get some rest. Then, good luck on your final.
To access root in bTree, you need to write Node.root.
Your Node is a top level class (read up about static inner classes). Hence your code
public static int size() //Public | sibling constructor
{
System.out.println("Debug0");
System.out.println(root.value);
return size(root);
}
won't work, you need to create a root Node.
Furthermore, I think your definition
Node root = new Node("ROOT");
is not necessary in Node, unless you want a reference back to the root node from every node, which I find a bit ugly :-0
Finally, why do you use the class bTree at all? You can identify a Node n with the tree that is rooted at n. I.e. put the size method within node.

Skip nodes during binary tree traversal

I need to traverse a binary tree, skipping the children of any node for which a condition is met.
This implements a tree-guided clustering approach; the leaves of a subtree are considered a cluster when they collectively meet the condition.
It seems like the place to start would be pre-order traversal, but I'm not sure how to modify the algorithm to skip all the children of the current node.
Update
In addition to the two (correct) answers below, one can use the following Java libraries:
MyArch TreeIter - Generic (with adapter class) tree traversal, with child skipping and dynamic maximum traversal depth
Phylosoft Forester - Tree implementation with getAllExternalDescendants and a Newick-to-XML converter
If by skipping all the children you mean not just direct descendants but their entire subtrees, you can do the following:
public void traverse(Node n){
if (n==null)
return;
doSomethingWith(n);
if (!conditionIsMet(n)){
traverse(n.left);
traverse(n.right);
}
}
the first part is easy:
class Tree {
Tree(int data) {
this.data = data;
}
Tree left, right;
Object object;
int data;
}
public class Main {
static void myPreorder(Tree tree) {
if (tree == null) return;
if (tree.data > 2) {
System.out.println("skipping " + tree.data);
return;
}
System.out.println("visiting " + tree.data);
myPreorder(tree.left);
myPreorder(tree.right);
}
public static void main(String[] args) {
Tree root = new Tree(1);
root.left = new Tree(2);
root.right = new Tree(3);
root.right.left = new Tree(4);
root.right.right = new Tree(5);
myPreorder(root);
}
}
the second part: " ... the leaves of a subtree are considered a cluster when they collectively meet the condition. ..." is hard. you would need to examine all of the leaves of a node to see that they met the skip condition.

Categories

Resources