How to Build a Binary Tree from a String Expression - java

Given a String such as this one, (((!D!)B!)A((!F(!H!))C(!G!))) with no white space. How would you build a binary tree?
I am supposed to implement a constructor and build it with an inoder traversal. This String would output
Any help/tips would be very appreciated!!!

Try this.
static Node parse(String input) {
return new Object() {
final int length = input.length();
int index = 0;
int ch = get();
int get() { return ch = index < length ? input.charAt(index++) : -1; }
Node node() {
if (ch == '!') {
get();
return null;
} else if (ch == '(') {
get();
Node left = node();
char data = (char)ch;
get();
Node right = node();
if (ch != ')')
throw new RuntimeException("')' expected");
get();
return new Node(left, data, right);
} else
throw new RuntimeException("'!' or '(' expected");
}
Node parse() {
Node node = node();
if (ch != -1)
throw new RuntimeException("extra string: " + input.substring(index - 1));
return node;
}
}.parse();
}
And
public static void main(String[] args) {
String input = "(((!D!)B!)A((!F(!H!))C(!G!)))";
Node root = parse(input);
System.out.println(root);
}
output:
Node[left=Node[left=Node[left=null, data=D, right=null], data=B, right=null], data=A, right=Node[left=Node[left=null, data=F, right=Node[left=null, data=H, right=null]], data=C, right=Node[left=null, data=G, right=null]]]

you can parse using recursion:
public BinaryTree(String t) {
this.root = parse(new StringReader(t));
}
private static Node parse(StringReader reader) {
char c = (char)reader.read();
if (c == '!')
return null;
if (c == '(') {
Node left = parse(reader);
char data = (char)reader.read();
Node right = parse(reader);
if (reader.read() != ')')
throw new IllegalArgumentException();
return new Node(left, data, right);
}
throw new IllegalArgumentException();
}

Related

Create and Search BST from a txt file

I am currently in an intro data structures class and am really struggling with one of our problems about Binary Search Trees. This is the first time I have implemented this data structure and am doing my best to learn it.
Problem:
The program is supposed to create and search a BST of name and occurrence data, based upon the census data of babies born that year. We are given this data in a txt file.
I am having a lot of difficulty figuring out why it is not working. I am really just looking for someone to lead me in the right direction from here and give me some good feedback on what I already have because I feel really lost! My current work is below. I am implementing this in java. Thanks in advance!
public class Node {
String name;
int data;
Node leftChild;
Node rightChild;
public Node (String n, int d) {
name = n;
data = d;
}
public class BinarySearchTree` {
public static Node root;
public void addNode(String name, int data) {
Node newNode = new Node(name, data);
if (root == null) {
root = newNode;
} else {
Node focusNode = root;
Node parent;
while(true) {
parent = focusNode;
if (name.compareTo(focusNode.name) < 0) {
focusNode = focusNode.leftChild;
if (focusNode == null) {
parent.leftChild = newNode;
return;
} else {
focusNode = focusNode.rightChild;
if (focusNode == null) {
parent.rightChild = newNode;
return;
}
}
}
}
}
}
public Node searchName(String name) {
Node focusNode = root;
while (!focusNode.name.equals(name)) {
if (name.compareTo(focusNode.name) < 0) {
focusNode = focusNode.leftChild;
} else {
focusNode = focusNode.rightChild;
}
if (focusNode == null) {
return null;
}
}
return focusNode;
}
public static void main(String[] args) throws Exception {
BinarySearchTree tree = new BinarySearchTree();
FileReader file = new FileReader("/Users/mattspahr/Desktop/test.txt");
BufferedReader reader = new BufferedReader(file);
String str = null,
name = null,
num = null;
int data;
while(reader.readLine() != null) {
str = reader.readLine();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c >= '0' || c <= '9') {
name = str.substring(0, i);
}
num = str.replaceAll("[^0-9]" , "");
}
data = Integer.parseInt(num);
tree.addNode(name,data);
Node n = tree.searchName("Buffy ");
System.out.println(n);
}
}
}

Adding Number Represented by Linked List

I'm stuck on this problem:
You have two numbers represented by a linked list, where each node contains a single digit. The digits are stored in reverse order, such that the 1’s digit is at the head of the list. Write a function that adds the two numbers and returns the sum as a linked list.
EXAMPLE
Input: (3 -> 1 -> 5), (5 -> 9 -> 2)
Output: 8 -> 0 -> 8
The problem is that my result is 8 8 while the result should be 8 0 8.
I printed out the sum and it is 8 10 8 so it should work.
Any ideas?
Here is my code:
public Node addNumbers(Node number1, Node number2) {
if(number1 == null && number2 == null)
return null;
Node sumOf = null;
int sum = 0;
int carry = 0;
while(number1 != null && number2 != null) {
sum = number1.data + number2.data + carry;
System.out.println(sum);
// update carry for next operation
if(sum > 9)
carry = 1;
else
carry = 0;
if(sum > 9) {
if(sumOf == null) {
sumOf = new Node(sum % 10);
} else {
sumOf.next = new Node(sum % 10);
}
} else {
if(sumOf == null) {
sumOf = new Node(sum);
} else {
sumOf.next = new Node(sum);
}
}
number1 = number1.next;
number2 = number2.next;
}
return sumOf;
}
public void toString(Node node) {
System.out.println();
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
public static void main(String[] args) {
AddTwoNumbers add = new AddTwoNumbers();
number1 = new Node(3);
number1.next = new Node(1);
number1.next.next = new Node(5);
number2 = new Node(5);
number2.next = new Node(9);
number2.next.next = new Node(2);
System.out.println("numbers: ");
add.toString(number1);
add.toString(number2);
System.out.println();
System.out.println("after adding: ");
add.toString(add.addNumbers(number1, number2));
}
}
You only ever set sumOf (if it is null) and sumOf.next (if sumOf is not null). Your resulting list therefore never has more than two elements. You need to track the current tail of your list and append there, instead of always appending to sumOf.
Additionally, you need to handle the cases where one input number has more digits than the other, and where you have non-zero carry after exhausting all the input digits. You do not presently handle either.
Here is the solution, do note that i carry forward when the sum of two integers is greater than 9 else i continue with the sum of next integers from both the list.
class Node {
private Object data;
private Node next;
public Object getData() { return data; }
public void setData(Object data) { this.data = data; }
public Node getNext() { return next; }
public void setNext(Node next) { this.next = next; }
public Node(final Object data, final Node next) {
this.data = data;
this.next = next;
}
#Override
public String toString() { return "Node:[Data=" + data + "]"; }
}
class SinglyLinkedList {
Node start;
public SinglyLinkedList() { start = null; }
public void addFront(final Object data) {
// create a reference to the start node with new data
Node node = new Node(data, start);
// assign our start to a new node
start = node;
}
public void addRear(final Object data) {
Node node = new Node(data, null);
Node current = start;
if (current != null) {
while (current.getNext() != null) {
current = current.getNext();
}
current.setNext(node);
} else {
addFront(data);
}
}
public void deleteNode(final Object data) {
Node previous = start;
if (previous == null) {
return;
}
Node current = previous.getNext();
if (previous != null && previous.getData().equals(data)) {
start = previous.getNext();
previous = current;
current = previous.getNext();
return;
}
while (current != null) {
if (current.getData().equals(data)) {
previous.setNext(current.getNext());
current = previous.getNext();
} else {
previous = previous.getNext();
current = previous.getNext();
}
}
}
public Object getFront() {
if (start != null) {
return start.getData();
} else {
return null;
}
}
public void print() {
Node current = start;
if (current == null) {
System.out.println("SingleLinkedList is Empty");
}
while (current != null) {
System.out.print(current);
current = current.getNext();
if (current != null) {
System.out.print(", ");
}
}
}
public int size() {
int size = 0;
Node current = start;
while (current != null) {
current = current.getNext();
size++;
}
return size;
}
public Node getStart() {
return this.start;
}
public Node getRear() {
Node current = start;
Node previous = current;
while (current != null) {
previous = current;
current = current.getNext();
}
return previous;
}
}
public class AddNumbersInSinglyLinkedList {
public static void main(String[] args) {
SinglyLinkedList listOne = new SinglyLinkedList();
SinglyLinkedList listTwo = new SinglyLinkedList();
listOne.addFront(5);
listOne.addFront(1);
listOne.addFront(3);
listOne.print();
System.out.println();
listTwo.addFront(2);
listTwo.addFront(9);
listTwo.addFront(5);
listTwo.print();
SinglyLinkedList listThree = add(listOne, listTwo);
System.out.println();
listThree.print();
}
private static SinglyLinkedList add(SinglyLinkedList listOne, SinglyLinkedList listTwo) {
SinglyLinkedList result = new SinglyLinkedList();
Node startOne = listOne.getStart();
Node startTwo = listTwo.getStart();
int carry = 0;
while (startOne != null || startTwo != null) {
int one = 0;
int two = 0;
if (startOne != null) {
one = (Integer) startOne.getData();
startOne = startOne.getNext();
}
if (startTwo != null) {
two = (Integer) startTwo.getData();
startTwo = startTwo.getNext();
}
int sum = carry + one + two;
carry = 0;
if (sum > 9) {
carry = sum / 10;
result.addRear(sum % 10);
} else {
result.addRear(sum);
}
}
return result;
}
}
Sample Run
Node:[Data=3], Node:[Data=1], Node:[Data=5]
Node:[Data=5], Node:[Data=9], Node:[Data=2]
Node:[Data=8], Node:[Data=0], Node:[Data=8]
**#In Python:-**
class Node():
def __init__(self,value):
self.value=value
self.nextnode=None
class LinkedList():
def __init__(self):
self.head=None
def add_element(self,value):
node=Node(value)
if self.head is None:
self.head =node
return
crnt_node=self.head
while crnt_node.nextnode is not None:
crnt_node=crnt_node.nextnode
crnt_node.nextnode=node
def reverse_llist(self):
crnt_node=self.head
if crnt_node == None:
print('Empty Linkned List')
return
old_node = None
while crnt_node:
temp_node = crnt_node.nextnode
crnt_node.nextnode = old_node
old_node = crnt_node
crnt_node = temp_node
self.head = old_node
def converted_llist(self):
crnt_node=self.head
carry_value=0
while True:
#print(crnt_node.value)
if (crnt_node.value+1)%10==0:
carry_value=1
crnt_node.value=0
print(crnt_node.value,end='->')
else:
print(crnt_node.value+carry_value,end='->')
if crnt_node.nextnode is None:
break
crnt_node=crnt_node.nextnode
print('None')
def print_llist(self):
crnt_node=self.head
while True:
print(crnt_node.value,end='->')
if crnt_node.nextnode is None:
break
crnt_node=crnt_node.nextnode
print('None')
list_convert=LinkedList()
list_convert.add_element(1)
list_convert.print_llist()
list_convert.add_element(9)
list_convert.print_llist()
list_convert.add_element(9)
list_convert.print_llist()
list_convert.add_element(9)
list_convert.print_llist()
list_convert.reverse_llist()
list_convert.print_llist()
list_convert.converted_llist()

Trouble creating append method to assist in replacing substrings in LinkedList

I have the methods replace() and append() to allow the replace method to replace the characters of a sub-string "LString" with the characters in "lStr" in a Linked List class LString. However im having trouble resolving my append methods in my replace class.
It may be because im not providing a node constructor with a LString parameter. Im not certain how to correct the issue. The relevant methods are at the very bottom of my class.
public class LString {
node front;
node end;
int length;
LString next;
char letter;
// create node class
public class node {
char data;
node next;
public node(LString newData) {
LString data;
}
public node(char newData, node newNext) {
data = newData;
next = newNext;
}
}
// LString constructor
// constructs LString object representing empty list of chars
public LString() {
this.length = 0;
this.front = null;
}
// Construct LString copy of original parameter
public LString(String original) {
//assign first char to front
node curr = this.front;
this.length = original.length();
// loop through
for (int i = 0; i < original.length(); i++) {
if (i == 0) {
front = new node(original.charAt(i), null);
curr = front;
} else {
curr.next = new node(original.charAt(i), null);
curr = curr.next;
}
}
}
// return length in this LString
// can use in LString constructor
public int length() {
return this.length;
}
//create and return string with contents of LString
public String toString() {
// use string builder to meet time limit
StringBuilder builder = new StringBuilder();
if (front == null) {
return "";
} else {
node curr = front;
while (curr != null) {
builder.append(curr.data);
curr = curr.next;
}
return builder.toString();
}
}
//compares string lists 0 if equal -1 if less, and 1 if greater
public int compareTo(LString anotherLString) {
//save lowest length of strings
int minLength;
// get front spots
node curr = this.front;
node otherCurr = anotherLString.front;
// get lengths
int thisString = length();
int otherString = anotherLString.length();
// get shortest length of 2 strings
if (thisString < otherString) {
minLength = thisString;
} else {
minLength = otherString;
}
//go through characters in each string and compare for lexicographic order
int iterate = 0;
while (iterate < minLength) {
char string1Char = curr.data;
char string2Char = otherCurr.data;
if (string1Char != string2Char) {
return string1Char - string2Char;
}
iterate++;
curr = curr.next;
otherCurr = otherCurr.next;
}
return thisString - otherString;
}
//Return true if LString represents the same list of characters as other
#Override
public boolean equals(Object other) {
if (other == null || !(other instanceof LString))
return false;
else {
// use compareTo to determine if strings are the same
LString otherLString = (LString) other;
if (compareTo(otherLString) == 0) {
return true;
} else {
return false;
}
}
}
//Return the char at the given index in this LString.
public char charAt(int index) {
int length = this.length();
// check for index out of bounds
if (index < 0 || index >= length) {
throw new IndexOutOfBoundsException();
}
// returns char at index
node curr = front;
for (int i = 0; i < index; i++) {
curr = curr.next;
}
return curr.data;
}
//Set the char at the given index in this LString to ch.
public void setCharAt(int index, char ch) {
// check for index out of bounds
int length = this.length();
if (index < 0 || index >= length) {
throw new IndexOutOfBoundsException();
}
// replaces char at index
node curr = front;
for (int i = 0; i < index; i++) {
curr = curr.next;
}
curr.next = new node(curr.data, curr.next);
curr.data = ch;
}
//Returns a new LString that is a sub-string of this LString.
public LString substring(int start, int end) {
LString newLString = new LString();
// handle exceptions
if (start < 0 || start > end) {
throw new IndexOutOfBoundsException();
} else if (end > this.length()) {
throw new IndexOutOfBoundsException();
//return null in special case (empty LString)
} else if (start == end) {
//&& end == this.length()
return newLString;
} else {
node node = this.front;
for (int i = 0; i < start; i++) {
node = node.next;
// insert substring
}
node copy = new node(node.data);
newLString.front = copy;
for (int i = start + 1; i < end; i++) {
node = node.next;
copy = copy.next = new node(node.data);
}
return newLString;
}
}
// Replaces this characters in a sub-string of this LString with the characters in lStr.
public LString replace(int start, int end, LString lStr) {
// handle exceptions
if (start < 0 || start > end) {
throw new IndexOutOfBoundsException();
} else if (end > this.length()) {
throw new IndexOutOfBoundsException();
}
LString replacedLs = new LString();
replacedLs.append(substring(0, start));
replacedLs.append(lStr);
replacedLs.append(substring(end, this.length));
return replacedLs;
}
//append helper method
public void append(LString data) {
this.length++;
if (front == null) {
front = new node(data);
return;
}
node curr = front;
while (curr.next != null) {
curr = curr.next;
}
curr.next = new node(data);
}
}
I appreciate any help, thank you.
Look at your node constructor, it simply does nothing:
public node(LString newData) {
LString data;
}
to make it work you should assign all LString.front fields to the current object, so:
public node(LString newData) {
this.data = newData.front.data;
this.next = newData.front.next;
}

LinkedList NullPointerException?

Hey I can't seem to get my code to work, there is something wrong with the constructor and I just can't figure out what it is.
I had it working for the constructor and tried it for some of the methods but even then it still gave me NullPointerException
import java.util.NoSuchElementException;
public class LinkedString
{
//Required Nodes/counters to track positions in LinkedList
private Node start;
private Node end;
private int counter;
private int i = 0;
//Inner class Node provides the node object required to create links
private class Node
{
public char data;
public Node next;
}
//This constructor allows the user to input a array of characters
//and have them created into a LinkedString object
public LinkedString(char[] value)
{
start.data = value[0];
counter = 0;
for(int i = 0 ; i < value.length ; i++)
{
if ( start == null)
{
start.data = value[i];
start.next = end;
counter++;
}
else
{
Node newNode = new Node();
newNode.data = value[i];
end.next = newNode;
newNode.next = null;
end = newNode;
counter++;
}
}
}
//This constructor allows the user to input a String
//getting each character and creating it into a LinkedString object
public LinkedString(String value)
{
counter=0;
for(int i = 0; i < value.length(); i++)
{
if(start == null)
{
start.data = value.charAt(i);
start.next = end;
counter++;
}
else
{
Node newNode = new Node();
newNode.data=value.charAt(i);
end.next = newNode;
newNode.next = null;
end = newNode;
}
}
}
//This accessor returns a value at the specified index
//The 1st character has an index of 0 and will throw
//a no such element exception if there is no char # given index
public char charAt(int index)
{
Node current = start;
boolean found = false;
char temp = 0;
int i = 0;
while (current.next != null && i <= index)
{
current = current.next;
if(i == index)
{
found = true;
//Return done, and Data is wrong Edit.
}
i++;
temp = current.data;
}
if(found == false) {
throw new NoSuchElementException();
}
return temp;
}
//concat connects two linkedString objects together and updates the
//counter for how many chars are in the combined list
public LinkedString concat(LinkedString value)
{
end.next = value.start;
end = value.end;
counter = counter + value.length();
return value;
}
//isEmpty checks to see if the list has a initial value
//if it doesnt its empty and returns true
public boolean isEmpty()
{
if(start == null)
{
return true;
}
else
{
return false;
}
}
//length() returns the counter variable which counts the number of
// characters in the linked string
public int length()
{
return counter;
}
//substring returns a copy of the linked string from a specified point
//to another, if the user attempts to copy a value from a not existing
//index point it throws NoSuchElementException
public Node substring(int startIndex, int endIndex)
{
Node current = start;
Node sIndex;
Node eIndex;
Node copy = null;
int i = 0;
while(current.next != null && i <= startIndex)
{
current = current.next;
if(i == startIndex)
{
sIndex = current;
sIndex.next = copy;
while(current.next != null && i <= endIndex)
{
current = current.next;
copy.next = current;
copy = current;
if(i == endIndex)
{
eIndex = current;
eIndex.next = null;
copy.next = eIndex;
}
i++;
}
if(i < endIndex)
throw new NoSuchElementException();
}
i++;
}
return copy;
}
}
public class LinkedStringMain {
public static void main(String[] args) {
LinkedString linked = new LinkedString("stack");
System.out.println(" " + linked.charAt(0));
System.out.println(" " + linked.isEmpty());
}
}
The error is that start is not being initialized in your either of your constructors after you check if it is null. To fix this, initialize start using start = new Node();. The changes are implemented below:
//This constructor allows the user to input a array of characters
//and have them created into a LinkedString object
public LinkedString(char[] value)
{
start.data = value[0];
counter = 0;
for(int i = 0 ; i < value.length ; i++)
{
if ( start == null)
{
start = new Node(); //initialize start
start.data = value[i];
start.next = end;
counter++;
}
else
{
Node newNode = new Node();
newNode.data = value[i];
end.next = newNode;
newNode.next = null;
end = newNode;
counter++;
}
}
}
//This constructor allows the user to input a String
//getting each character and creating it into a LinkedString object
public LinkedString(String value)
{
counter=0;
for(int i = 0; i < value.length(); i++)
{
if(start == null)
{
start = new Node(); //initialize start
start.data = value.charAt(i);
start.next = end;
counter++;
}
else
{
Node newNode = new Node();
newNode.data=value.charAt(i);
end.next = newNode;
newNode.next = null;
end = newNode;
}
}
}

How to merge single node trees into large tree

I have a project which is to “Start with the tree.java program (Listing 8.1) and modify it to create a binary
tree from a string of letters (like A, B, and so on) entered by the user. Each
letter will be displayed in its own node. Construct the tree so that all the nodes
that contain letters are leaves. Parent nodes can contain some non-letter
symbol like +. Make sure that every parent node has exactly two children.
Don’t worry if the tree is unbalanced.” The book gives us a hint on how to begin. “One way to begin is by making an array of trees. (A group of unconnected trees
is called a forest.) Take each letter typed by the user and put it in a node. Take
each of these nodes and put it in a tree, where it will be the root. Now put all
these one-node trees in the array. Start by making a new tree with + at the root
and two of the one-node trees as its children. Then keep adding one-node trees
from the array to this larger tree. Don’t worry if it’s an unbalanced tree.”
import java.io.*;
import java.util.*;
class Node
{
public String iData; // data item (key)
public Node leftChild; // this node’s left child
public Node rightChild; // this node’s right child
public void displayNode() // display ourself
{
System.out.print('{');
System.out.print(iData);
System.out.print("} ");
}
} // end class Node
class Tree
{
private Node root; // first node of tree
public void setNode(Node newNode)
{root = newNode;}
public Node getNode()
{return root;}
// -------------------------------------------------------------
public Tree() // constructor
{ root = null; } // no nodes in tree yet
// -------------------------------------------------------------
public void traverse(int traverseType)
{
switch(traverseType)
{
case 1: System.out.print("nPreorder traversal: ");
preOrder(root);
break;
case 2: System.out.print("nInorder traversal: ");
inOrder(root);
break;
case 3: System.out.print("nPostorder traversal: ");
postOrder(root);
break;
}
System.out.println();
}
private void preOrder(Node localRoot)
{
if(localRoot != null)
{
System.out.print(localRoot.iData + " ");
preOrder(localRoot.leftChild);
preOrder(localRoot.rightChild);
}
}
// -------------------------------------------------------------
private void inOrder(Node localRoot)
{
if(localRoot != null)
{
inOrder(localRoot.leftChild);
System.out.print(localRoot.iData + " ");
inOrder(localRoot.rightChild);
}
}
// -------------------------------------------------------------
private void postOrder(Node localRoot)
{
if(localRoot != null)
{
postOrder(localRoot.leftChild);
postOrder(localRoot.rightChild);
System.out.print(localRoot.iData + " ");
}
}
// -------------------------------------------------------------
public void displayTree()
{
Stack globalStack = new Stack();
globalStack.push(root);
int nBlanks = 32;
boolean isRowEmpty = false;
System.out.println(
"......................................................");
while(isRowEmpty==false)
{
Stack localStack = new Stack();
isRowEmpty = true;
for(int j=0; j<nBlanks; j++)
System.out.print(' ');
while(globalStack.isEmpty()==false)
{
Node temp = (Node)globalStack.pop();
if(temp != null)
{
System.out.print(temp.iData);
localStack.push(temp.leftChild);
localStack.push(temp.rightChild);
if(temp.leftChild != null ||
temp.rightChild != null)
isRowEmpty = false;
}
else
{
System.out.print("--");
localStack.push(null);
localStack.push(null);
}
for(int j=0; j<nBlanks*2-2; j++)
System.out.print(' ');
} // end while globalStack not empty
System.out.println();
nBlanks /= 2;
while(localStack.isEmpty()==false)
globalStack.push( localStack.pop() );
} // end while isRowEmpty is false
System.out.println(
"......................................................");
} // end displayTree()
// -------------------------------------------------------------
}
public class Leaves
{
//function used to enter the single node trees into a larger tree
public static void enterLetters(Node localRoot, Tree[] nodeTree, int i)
{
if(localRoot != null && i == nodeTree.length)
{
if(nodeTree.length == i - 1)
{
localRoot.leftChild = nodeTree[i].getNode();
localRoot.rightChild = nodeTree[i + 1].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
}
else
{
Node plusNode = new Node();
plusNode.iData = "+";
localRoot.leftChild = plusNode;
localRoot.rightChild = nodeTree[i].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
}
}
}
public static void main(String[] args)
{
Tree[] forest = new Tree[10];
Scanner sc = new Scanner(System.in);
for(int i = 0; i < 10; i++)
{
String letter;
forest[i] = new Tree();
System.out.println("Enter a letter: ");
letter = sc.nextLine();
Node newNode = new Node();
newNode.iData = letter;
forest[i].setNode(newNode);
}
Tree letterTree = new Tree();
Node firstNode = new Node();
firstNode.iData = "+";
letterTree.setNode(firstNode);
enterLetters(letterTree.getNode(), forest, 0);
letterTree.displayTree();
}
}
My problem is trying to get the array of single node trees into the larger tree. I tried making a recursive function but when I display the larger tree it only shows the first node and it is as if the function enterLeaves never did it’s job.
This can't be correct:
public static void enterLetters(Node localRoot, Tree[] nodeTree, int i) {
if (localRoot != null && i == nodeTree.length) {
if (nodeTree.length == i - 1) {
localRoot.leftChild = nodeTree[i].getNode();
localRoot.rightChild = nodeTree[i + 1].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
} else {
Node plusNode = new Node();
plusNode.iData = "+";
localRoot.leftChild = plusNode;
localRoot.rightChild = nodeTree[i].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
}
}
}
When you enter this method: localRoot != null, i == 0, and nodeTree.length==10
So the if statement is failing. I am guess the if statement should read:
if (localRoot != null && i < nodeTree.length)
Also, I am pretty sure your second if statement is incorrect also; I believe it should be.
if (nodeTree.length-2 == i) {
localRoot.leftChild = nodeTree[i].getNode();
localRoot.rightChild = nodeTree[i + 1].getNode();
return;
}
Instead of:
if (nodeTree.length == i - 1) {
localRoot.leftChild = nodeTree[i].getNode();
localRoot.rightChild = nodeTree[i + 1].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
}
You want to stop when you have two Nodes left to process (nodeTree.length-2 == i) and after you do that you should return instead of entering the remaining letters.
Here's what I came up with that works:
Node.java
/** Represents a node in a binary tree data structure */
public class Node {
private char letter;
private Node leftChild;
private Node rightChild;
public Node(char letter) {
this.letter = letter;
}
public void setRightChild(Node rightChild) {
this.rightChild = rightChild;
}
public Node getRightChild() {
return rightChild;
}
public void setLeftChild(Node leftChild) {
this.leftChild = leftChild;
}
public Node getLeftChild() {
return leftChild;
}
/** Returns a String representation of this node. */
#Override
public String toString() {
return "" + letter;
}
}
Tree.java
import java.util.Stack;
/**
* A binary tree
*/
public class Tree {
private Node root;
public void setRoot(Node root) {
this.root = root;
}
public void addToLeft(Node node) {
root.setLeftChild(node);
}
public void addToRight(Node node) {
root.setRightChild(node);
}
public Node getRoot() {
return root;
}
public void displayTree() {
Stack<Node> globalStack = new Stack<>();
globalStack.push(root);
int nBlanks = 32;
boolean isRowEmpty = false;
System.out.println(
"......................................................");
while (!isRowEmpty) {
Stack<Node> localStack = new Stack<>();
isRowEmpty = true;
for (int j = 0; j < nBlanks; j++)
System.out.print(' ');
while (!globalStack.isEmpty()) {
Node temp = (Node) globalStack.pop();
if (temp != null) {
System.out.print(temp);
localStack.push(temp.getLeftChild());
localStack.push(temp.getRightChild());
if (temp.getLeftChild() != null ||
temp.getRightChild() != null)
isRowEmpty = false;
} else {
System.out.print("--");
localStack.push(null);
localStack.push(null);
}
for (int j = 0; j < nBlanks * 2 - 2; j++)
System.out.print(' ');
} // end while globalStack not empty
System.out.println();
nBlanks /= 2;
while (!localStack.isEmpty())
globalStack.push(localStack.pop());
} // end while isRowEmpty is false
System.out.println(
"......................................................");
}
}
Forest.java
/**
* A collection of OneNodeTrees combined together in one tree
*/
public class Forest {
private Tree[] forest;
private int forestIndex;
public Forest(int numTrees) {
forest = new Tree[numTrees];
forestIndex = 0;
}
public boolean add(Tree tree) {
if(forestIndex < forest.length) {
forest[forestIndex++] = tree;
return true;
} else {
return false;
}
}
public Tree createMainTree() {
Tree firstTree = new Tree();
firstTree.setRoot(new Node('+'));
firstTree.addToLeft(forest[0].getRoot());
firstTree.addToRight(forest[1].getRoot());
forest[1] = firstTree;
int mainTreeIndex = 0;
Tree tempTree;
for(mainTreeIndex = 2; mainTreeIndex < forest.length; mainTreeIndex++) {
tempTree = new Tree();
tempTree.setRoot(new Node('+'));
tempTree.addToLeft(forest[mainTreeIndex - 1].getRoot());
tempTree.addToRight(forest[mainTreeIndex].getRoot());
forest[mainTreeIndex] = tempTree;
}
return forest[mainTreeIndex - 1];
}
public static void main(String[] args) {
final int numberOfTrees = 6;
Forest forest = new Forest(numberOfTrees);
// Add characters starting from A which has ASCII value 65
int charLimit = 65 + numberOfTrees;
for(int i = 65; i < charLimit; i++) {
// Make new node.
Node newNode = new Node((char) i);
// Add that node to Tree as a root.
Tree newTree = new Tree();
newTree.setRoot(newNode);
// And add that one-node tree to forest(array)
forest.add(newTree);
}
Tree mainTree = forest.createMainTree();
mainTree.displayTree();
}
}
if(localRoot != null && i == nodeTree.length -1)
if you do not subtract one from node tree length you will have a duplicate child under the final parent node with 2 children

Categories