I want to write a java program to arrange the given employee ID in a Binary Search Tree format and then find the immediate manager of any given employee in the organization.
Employee Binary Tree:
Input Format
The first line should contain the number of employees "n" to be inserted in the Tree
The second line should contain the employee ID for which we need to find the immediate manager.
The next "n" lines should contain the employee IDs to form the binary search Tree.
Sample:
Below is the code with which I have intialized the tree successfully. I need help on how to search the parent node for a given child node.
import java.util.Scanner;
class BinarySearchTree {
/* Class containing left and right child of current node and key value*/
class Node {
int data;
int key;
Node left, right;
public Node(int item) {
key = item;
left = right = null;
}
}
// Root of BST
Node root;
// Constructor
BinarySearchTree() {
root = null;
}
// This method mainly calls insertRec()
void insert(int key) {
root = insertRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node insertRec(Node root, int key) {
/* If the tree is empty, return a new node */
if (root == null) {
root = new Node(key);
return root;
}
/* Otherwise, recur down the tree */
if (key < root.key)
root.left = insertRec(root.left, key);
else if (key > root.key)
root.right = insertRec(root.right, key);
/* return the (unchanged) node pointer */
return root;
}
// This method mainly calls InorderRec()
void inorder() {
inorderRec(root);
}
// A utility function to do inorder traversal of BST
void inorderRec(Node root) {
if (root != null) {
inorderRec(root.left);
System.out.println(root.key);
inorderRec(root.right);
}
}
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
//int sch = sc.nextInt();
for (int i=0;i<num;i++) {
tree.insert(sc.nextInt());
}
tree.inorder();
}
}
When you write a recursive method, the first thing you need is a condition that terminates the recursion. In your case there are two conditions, as follows.
You find the employee that you are searching for.
You reach the end of the tree.
The recursion needs to terminate if either of the above conditions is true. In your case, terminating the recursion means the method must return a value.
If the terminating condition is not true, the method needs to call itself but with different values for the method parameters.
Here is my recursive search method. More explanation appears after the code.
int search(int employee, int manager, Node node) {
if (node != null) {
if (employee == node.key) {
return manager;
}
manager = node.key;
if (employee < node.key) {
return search(employee, manager, node.left);
}
else {
return search(employee, manager, node.right);
}
}
else {
return -1;
}
}
The method parameters are as follows:
employee - the employee to search for
manager - the manager of the next parameter
node - a node in the tree that will be checked to see if its key is the employee we are searching for
We start searching at the root of the tree and traverse down through the tree nodes. Hence the initial call to the method, which would probably be in method main() would be:
tree.search(sch, -1, tree.root)
According to your sample data, sch is 55. Note that in the initial call, the manager is -1 since the root of the tree does not have a manager. So if sch equals the root key, the method will return -1.
Since we know that the key in the left child of a node is lower and the right child's key is higher, we don't have to search every node. So the method calls itself with the relevant child node. Also we save the current key because if the child node's key is the one we are searching for, then this node's key is the manager.
If the node parameter in method search() is null, that means we have reached the end of the tree which means we have not found the value we are searching for. The value -1 (minus one) is a convention for a value that indicates that the search failed. Method indexOf() in class String is an example of a method also using that convention.
Finally, I used the code you posted in your question. I only added the above method as well as a call to that method from method main(). I added the initial call to method search() as the last line in method main().
For completeness, here is the entire code:
import java.util.Scanner;
public class BinarySearchTree {
class Node {
int key;
Node left, right;
public Node(int item) {
key = item;
left = right = null;
}
}
// Root of BST
Node root;
// Constructor
BinarySearchTree() {
root = null;
}
// This method mainly calls insertRec()
void insert(int key) {
root = insertRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node insertRec(Node root, int key) {
/* If the tree is empty, return a new node */
if (root == null) {
root = new Node(key);
return root;
}
/* Otherwise, recur down the tree */
if (key < root.key)
root.left = insertRec(root.left, key);
else if (key > root.key)
root.right = insertRec(root.right, key);
/* return the (unchanged) node pointer */
return root;
}
// This method mainly calls InorderRec()
void inorder() {
inorderRec(root);
}
// A utility function to do inorder traversal of BST
void inorderRec(Node root) {
if (root != null) {
inorderRec(root.left);
System.out.println(root.key);
inorderRec(root.right);
}
}
// The method I added.
int search(int employee, int manager, Node node) {
if (node != null) {
if (employee == node.key) {
return manager;
}
manager = node.key;
if (employee < node.key) {
return search(employee, manager, node.left);
}
else {
return search(employee, manager, node.right);
}
}
else {
return -1;
}
}
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int sch = sc.nextInt();
for (int i = 0; i < num; i++) {
tree.insert(sc.nextInt());
}
tree.inorder();
System.out.printf("Manager is %d%n", tree.search(sch, -1, tree.root)); // changed this line to print only manager.
}
}
Related
I found binary search tree insertion java code on the website,
https://www.geeksforgeeks.org/binary-search-tree-set-1-search-and-insertion/
and part of the code is like below,
if (root == null) {
root = new Node(key);
return root;
}
and I thought we don`t need any return statement because root itself is reference type(Node), so updating root is enough.
so I changed the code like this.
class BinarySearchTree {
class Node {
int key;
Node left, right;
public Node(int item) {
key = item;
left = right = null;
}
}
Node root;
BinarySearchTree() {
root = null;
}
void insert(int key) {
insertRec(root, key);
}
/* A recursive function to insert a new key in BST */
void insertRec(Node root, int key) {
if (root == null) {
root = new Node(key);
}
if (key < root.key)
insertRec(root.left, key);
else if (key > root.key)
insertRec(root.right, key);
}
// Driver Program to test above functions
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
tree.insert(50);
tree.insert(20);
System.out.println(tree.root);
}
}
but tree.root returns null.
why is this happening?
root = new Node(key); updates a local variable, it doesn't update the root of the tree (this.root), and it shouldn't. Therefore this assignment doesn't update the tree.
When you return the newly created Node (as in the original code that you changed did), you can assign it to be either the root of the tree (as the original code did with root = insertRec(root, key);) or the left or right child of an existing tree node (as the original code did with root.left = insertRec(root.left, key); or root.right = insertRec(root.right, key);). That's how the tree is updated.
EDIT: Java is a pass by value language, not pass by reference. When you pass a variable to a method, that method can't change the value of the passed variable. If you pass a variable whose value is null to a method, and that method assigns a value to it, the variable will still contain null once the method returns.
Like others already have pointed out, you need to update your root every time you insert an element.
Just return the value of root and update your global root for the tree.
Node insertRec(Node root, int key) {
if (root == null) {
root = new Node(key);
return root;
}
if (key < root.key)
root.left = insertRec(root.left, key);
else
root.right = insertRec(root.right, key);
return root;
}
Finally, update your global root.
tree.root = tree.insert(50);
tree.root = tree.insert(20);
Full code:
class BinarySearchTree {
class Node {
int key;
Node left, right;
public Node(int item) {
key = item;
left = right = null;
}
}
Node root;
BinarySearchTree() {
root = null;
}
Node insert(int key) {
return insertRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node insertRec(Node root, int key) {
if (root == null) {
root = new Node(key);
return root;
}
if (key < root.key)
root.left = insertRec(root.left, key);
else
root.right = insertRec(root.right, key);
return root;
}
// Driver Program to test above functions
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
tree.root = tree.insert(50);
tree.root = tree.insert(20);
System.out.println(tree.root.key);
}
}
/* A recursive function to insert a new key in BST */
void insertRec(Node root, int key) {
if (root == null) {
root = new Node(key);
}
}
It is called "shadows effect".
That mean your root note from parent class is shadowed by root node in your method.
To fixed it use "this.root" to reference to parent class and initialized the object.
More information : read "Shadowing" in the article. It explained very well.
http://ocpj8.javastudyguide.com/ch03.html
In your constructor you don't initialise a rootNode. Your key is also not transformed in a Node and you don't set your inserted Node to a left or right node. Also you don't do anything with a node that is equal to the current node you traverse.
I am trying to write a non-recursive method that removes a node within a binary search tree if it contains the given input value int x in Java. I figured I need to use a stack but can't seem to figure out how to remove the node without calling the function on itself.
This is my TreeNode class as of now.
class TreeNode {
private int data; // data item (key)
private TreeNode left; // this node's left child
private TreeNode right; // this node's right child
// The "external node" is a special node that acts as a sentinel.
private final static TreeNode externalnode = TreeNode.createExternalNode();
/* Return a TreeNode that represents an "external node"*/
public static TreeNode getExternalNode() {
return externalnode;
}
/* Creates a new TreeNode with no children.
*/
public TreeNode(int id) { // constructor
data = id;
left = externalnode;
right = externalnode;
}
I have tried this but cant get it to work.
public TreeNode removeB(int x){
if (this == externalnode) return externalnode;
TreeNode one = new TreeNode(this.data);
System.out.println(this);
Stack<TreeNode> s = new Stack();
s.push(one);
//System.out.println(s);
boolean check;
boolean check1;
while(check = true){
if(x == one.left.data){
System.out.println(one.left.data);
check = false;
return one.left;
}
if(x == one.right.data){
System.out.println(one.right.data);
check1 = false;
return one.right;
}
}
Your code needs to first perform a binary search to find the node to remove. In pseudo-code, it looks something like:
while (currentNode != null && currentNode.value != target) {
if (currentNode.value > target) {
currentNode = currentNode.left;
} else if (currentNode.value < target) {
currentNode = currentNode.right;
}
}
Once you've targeted that node, you replace it with one of its children, and then graft in the other orphaned child under it, just as you would add any node.
I've read all the posts related to this question, yet I am still having a very hard time understanding how to implement the algorithm.
I have a fully written BST with methods that recursively add, delete etc Student objects(the BST class is written for generics, though). I need to write a method that returns the rank of a student in the binary search tree based off their GPA, yet I do not understand how I should implement this. The Student class has a getGPA() method, so I know ill need to use that somehow.
Should I store the elements into an array then search for the index? If so, what's the best algorithm to accomplish this? Is there a better way to do this?
Here is the important parts of my BST class:
public int size()
// Returns the number of elements in this BST.
{
return recSize(root);
}
private int recSize(BSTNode<T> tree)
// Returns the number of elements in tree.
{
if (tree == null)
return 0;
else
return recSize(tree.getLeft()) + recSize(tree.getRight()) + 1;
}
private boolean recContains(T element, BSTNode<T> tree)
// Returns true if tree contains an element e such that
// e.compareTo(element) == 0; otherwise, returns false.
{
if (tree == null)
return false; // element is not found
else if (element.compareTo(tree.getInfo()) < 0)
return recContains(element, tree.getLeft()); // Search left subtree
else if (element.compareTo(tree.getInfo()) > 0)
return recContains(element, tree.getRight()); // Search right subtree
else
return true; // element is found
}
public boolean contains (T element)
// Returns true if this BST contains an element e such that
// e.compareTo(element) == 0; otherwise, returns false.
{
return recContains(element, root);
}
private T recGet(T element, BSTNode<T> tree)
// Returns an element e from tree such that e.compareTo(element) == 0;
// if no such element exists, returns null.
{
if (tree == null)
return null; // element is not found
else if (element.compareTo(tree.getInfo()) < 0)
return recGet(element, tree.getLeft()); // get from left subtree
else
if (element.compareTo(tree.getInfo()) > 0)
return recGet(element, tree.getRight()); // get from right subtree
else
return tree.getInfo(); // element is found
}
public T get(T element)
// Returns an element e from this BST such that e.compareTo(element) == 0;
// if no such element exists, returns null.
{
return recGet(element, root);
}
private BSTNode<T> recAdd(T element, BSTNode<T> tree)
// Adds element to tree; tree retains its BST property.
{
if (tree == null)
// Addition place found
tree = new BSTNode<T>(element);
else if (element.compareTo(tree.getInfo()) <= 0)
tree.setLeft(recAdd(element, tree.getLeft())); // Add in left subtree
else
tree.setRight(recAdd(element, tree.getRight())); // Add in right subtree
return tree;
}
public void add (T element)
// Adds element to this BST. The tree retains its BST property.
{
root = recAdd(element, root);
}
private void inOrder(BSTNode<T> tree)
// Initializes inOrderQueue with tree elements in inOrder order.
{
if (tree != null)
{
inOrder(tree.getLeft());
inOrderQueue.enqueue(tree.getInfo());
inOrder(tree.getRight());
}
}
private void preOrder(BSTNode<T> tree)
// Initializes preOrderQueue with tree elements in preOrder order.
{
if (tree != null)
{
preOrderQueue.enqueue(tree.getInfo());
preOrder(tree.getLeft());
preOrder(tree.getRight());
}
}
private void postOrder(BSTNode<T> tree)
// Initializes postOrderQueue with tree elements in postOrder order.
{
if (tree != null)
{
postOrder(tree.getLeft());
postOrder(tree.getRight());
postOrderQueue.enqueue(tree.getInfo());
}
}
public int reset(int orderType)
// Initializes current position for an iteration through this BST
// in orderType order. Returns current number of nodes in the BST.
{
int numNodes = size();
if (orderType == INORDER)
{
inOrderQueue = new LinkedUnbndQueue<T>();
inOrder(root);
}
else
if (orderType == PREORDER)
{
preOrderQueue = new LinkedUnbndQueue<T>();
preOrder(root);
}
if (orderType == POSTORDER)
{
postOrderQueue = new LinkedUnbndQueue<T>();
postOrder(root);
}
return numNodes;
}
After several failures, it seems I have found a workable solution. Instead of storing in a generic array with a fixed size, I decided to try an ArrayList instead. I use a recursive method to add each node inorder to the array list:
//recursive method used to copy BST to array list
public void recArrayList(BSTNode<T> tree, ArrayList<T> list)
{
if (tree == null)
{
return;
}
recArrayList(tree.getLeft(), list);
list.add(tree.getInfo());
recArrayList(tree.getRight(), list);
}
//converts BST to arraylist used for finding GPA rank
public ArrayList<T> toArrayList()
{
stuList = new ArrayList<T>();
recArrayList(root, stuList);
return stuList;
}
And finally in the class using the BST:
//returns the rank of student in BST based off GPA
public int rank(Student stu)
{
ArrayList<Student> stuList = stuGPA.toArrayList();
for (i = 0; i < stuList.size(); i++)
{
if (stuList.get(i) == stu)
{
return i + 1;
}
}
return 0;
}
I dont like using == to compare references so i'm working on changing that, but for now this seems to be functioning correctly. Ty for the comments, it inspired me to go a different route.
So this is my first java program, but I've done c++ for a few years. I wrote what I think should work, but in fact it does not. So I had a stipulation of having to write a method for this call:
tree.insertNode(value);
where value is an int.
I wanted to write it recursively, for obvious reasons, so I had to do a work around:
public void insertNode(int key) {
Node temp = new Node(key);
if(root == null) root = temp;
else insertNode(temp);
}
public void insertNode(Node temp) {
if(root == null)
root = temp;
else if(temp.getKey() <= root.getKey())
insertNode(root.getLeft());
else insertNode(root.getRight());
}
Thanks for any advice.
// In java it is little trickier as objects are passed by copy.
// PF my answer below.
// public calling method
public void insertNode(int key) {
root = insertNode(root, new Node(key));
}
// private recursive call
private Node insertNode(Node currentParent, Node newNode) {
if (currentParent == null) {
return newNode;
} else if (newNode.key > currentParent.key) {
currentParent.right = insertNode(currentParent.right, newNode);
} else if (newNode.key < currentParent.key) {
currentParent.left = insertNode(currentParent.left, newNode);
}
return currentParent;
}
Sameer Sukumaran
The code looks a little confusing with overloaded functions. Assuming member variables 'left' and 'right' to be the left child and right child of the BSTree respectively, you can try implementing it in the following way:
public void insert(Node node, int value) {
if (value < node.value)
{
if (node.left != null)
{
insert(node.left, value);
}
else
{
node.left = new Node(value);
}
}
else if (value > node.value)
{
if (node.right != null)
{
insert(node.right, value);
}
else
{
node.right = new Node(value);
}
}
}
........
public static void main(String [] args)
{
BSTree bt = new BSTree();
Node root = new Node(100);
bt.insert(root, 50);
bt.insert(root, 150);
}
You should have a look to this article. It helps to implement a tree structure and search, insert methods:
http://quiz.geeksforgeeks.org/binary-search-tree-set-1-search-and-insertion/
// This method mainly calls insertRec()
void insert(int key) {
root = insertRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node insertRec(Node root, int key) {
/* If the tree is empty, return a new node */
if (root == null) {
root = new Node(key);
return root;
}
/* Otherwise, recur down the tree */
if (key < root.key)
root.left = insertRec(root.left, key);
else if (key > root.key)
root.right = insertRec(root.right, key);
/* return the (unchanged) node pointer */
return root;
}
You can use standard Integer (wrapper for primitive int) object instead of creating a new object type Node. On latest java Integer/int auto-boxing is supported. Hence your method insertNode(int key) can take in Integer argument too (ensure it is not null).
EDIT: Pls ignore above comment. I did not understand your real question. You will have to overload insertNode(). I think you are right.
but where is temp when you insertNode?? With your current implementation temp is lost if root is not null.
I think you want something like
root.getLeft().insertNode(temp);
and
root.getRight().insertNode(temp);
i.e. To insert the new Node (temp) to either the left or the right subtree.
I've been trying to write a recursive string method for a binary search tree that returns a multiple line representation of a tree with preorder path info.
Each node should be prefaced by a series of < and > characters showing the path that leads from the root to that node. I'm not sure how to use a string prefix parameter that is extended by one character with each successive call.
The method should be able reproduce this example:
Tree:
15
/ \
12 18
/ / \
10 16 20
\ \
11 17
Expected Print Output:
15
<12
<<10
<<>11
>18
><16
><>17
>>20
I'm new to recursion and so far my actual print output isn't close enough after hours of messing with the code:
18
<17
<10
>15
<11
>12
16
20
Here's my tree node class that works properly:
/**
* A single binary tree node.
* <p>
* Each node has both a left or right child, which can be null.
*/
public class TreeNode<E> {
private E data;
private TreeNode<E> left;
private TreeNode<E> right;
/**
* Constructs a new node with the given data and references to the
* given left and right nodes.
*/
public TreeNode(E data, TreeNode<E> left, TreeNode<E> right) {
this.data = data;
this.left = left;
this.right = right;
}
/**
* Constructs a new node containing the given data.
* Its left and right references will be set to null.
*/
public TreeNode(E data) {
this(data, null, null);
}
/** Returns the item currently stored in this node. */
public E getData() {
return data;
}
/** Overwrites the item stored in this Node with the given data item. */
public void setData(E data) {
this.data = data;
}
/**
* Returns this Node's left child.
* If there is no left left, returns null.
*/
public TreeNode<E> getLeft() {
return left;
}
/** Causes this Node to point to the given left child Node. */
public void setLeft(TreeNode<E> left) {
this.left = left;
}
/**
* Returns this nodes right child.
* If there is no right child, returns null.
*/
public TreeNode<E> getRight() {
return right;
}
/** Causes this Node to point to the given right child Node. */
public void setRight(TreeNode<E> right) {
this.right = right;
}
}
Here's my binary search tree class with the toFullString() method near the bottom:
import java.util.*;
/**
* A binary search tree (BST) is a sorted ADT that uses a binary
* tree to keep all elements in sorted order. If the tree is
* balanced, performance is very good: O(n lg n) for most operations.
* If unbalanced, it performs more like a linked list: O(n).
*/
public class BinarySearchTree<E extends Comparable<E>> {
private TreeNode<E> root = null;
private int size = 0;
/** Creates an empty tree. */
public BinarySearchTree() {
}
public BinarySearchTree(Collection<E> col) {
List<E> list = new ArrayList<E>(col);
Collections.shuffle(list);
for (int i = 0; i < list.size() ; i++) {
add(list.get(i));
}
}
/** Adds the given item to this BST. */
public void add(E item) {
this.size++;
if (this.root == null) {
//tree is empty, so just add item
this.root = new TreeNode<E>(item);
}else {
//find where to insert, with pointer to parent node
TreeNode<E> parent = null;
TreeNode<E> curr = this.root;
boolean wentLeft = true;
while (curr != null) { //will execute at least once
parent = curr;
if (item.compareTo(curr.getData()) <= 0) {
curr = curr.getLeft();
wentLeft = true;
}else {
curr = curr.getRight();
wentLeft = false;
}
}
//now add new node on appropriate side of parent
curr = new TreeNode<E>(item);
if (wentLeft) {
parent.setLeft(curr);
}else {
parent.setRight(curr);
}
}
}
/** Returns the greatest (earliest right-most node) of the given tree. */
private E findMax(TreeNode<E> n) {
if (n == null) {
return null;
}else if (n.getRight() == null) {
//can't go right any more, so this is max value
return n.getData();
}else {
return findMax(n.getRight());
}
}
/**
* Returns item from tree that is equivalent (according to compareTo)
* to the given item. If item is not in tree, returns null.
*/
public E get(E item) {
return get(item, this.root);
}
/** Finds it in the subtree rooted at the given node. */
private E get(E item, TreeNode<E> node) {
if (node == null) {
return null;
}else if (item.compareTo(node.getData()) < 0) {
return get(item, node.getLeft());
}else if (item.compareTo(node.getData()) > 0) {
return get(item, node.getRight());
}else {
//found it!
return node.getData();
}
}
/**
* Removes the first equivalent item found in the tree.
* If item does not exist to be removed, throws IllegalArgumentException().
*/
public void remove(E item) {
this.root = remove(item, this.root);
}
private TreeNode<E> remove(E item, TreeNode<E> node) {
if (node == null) {
//didn't find item
throw new IllegalArgumentException(item + " not found in tree.");
}else if (item.compareTo(node.getData()) < 0) {
//go to left, saving resulting changes made to left tree
node.setLeft(remove(item, node.getLeft()));
return node;
}else if (item.compareTo(node.getData()) > 0) {
//go to right, saving any resulting changes
node.setRight(remove(item, node.getRight()));
return node;
}else {
//found node to be removed!
if (node.getLeft() == null && node.getRight() == null) {
//leaf node
return null;
}else if (node.getRight() == null) {
//has only a left child
return node.getLeft();
}else if (node.getLeft() == null) {
//has only a right child
return node.getRight();
}else {
//two children, so replace the contents of this node with max of left tree
E max = findMax(node.getLeft()); //get max value
node.setLeft(remove(max, node.getLeft())); //and remove its node from tree
node.setData(max);
return node;
}
}
}
/** Returns the number of elements currently in this BST. */
public int size() {
return this.size;
}
/**
* Returns a single-line representation of this BST's contents.
* Specifically, this is a comma-separated list of all elements in their
* natural Comparable ordering. The list is surrounded by [] characters.
*/
#Override
public String toString() {
return "[" + toString(this.root) + "]";
}
private String toString(TreeNode<E> n) {
//would have been simpler to use Iterator... but not implemented yet.
if (n == null) {
return "";
}else {
String str = "";
str += toString(n.getLeft());
if (!str.isEmpty()) {
str += ", ";
}
str += n.getData();
if (n.getRight() != null) {
str += ", ";
str += toString(n.getRight());
}
return str;
}
}
public String toFullString() {
StringBuilder sb = new StringBuilder();
toFullString(root, sb);
return sb.toString();
}
/**
* Preorder traversal of the tree that builds a string representation
* in the given StringBuilder.
* #param n root of subtree to be traversed
* #param sb StringBuilder in which to create a string representation
*/
private void toFullString(TreeNode<E> n, StringBuilder sb)
{
if (n == null)
{
return;
}
sb.append(n.getData().toString());
sb.append("\n");
if (n.getLeft() != null) {
sb.append("<");
} else if (n.getRight() != null) {
sb.append(">");
}
if (n.getLeft() != null || n.getRight() != null)
{
toFullString(n.getLeft(), sb);
toFullString(n.getRight(), sb);
}
}
/**
* Tests the BST.
*/
public static void main(String[] args) {
Collection collection = new ArrayList();
collection.add(15);
collection.add(12);
collection.add(18);
collection.add(10);
collection.add(16);
collection.add(20);
collection.add(11);
collection.add(17);
BinarySearchTree bst = new BinarySearchTree(collection);
//System.out.println(bst);
String temp = bst.toFullString();
System.out.println(temp);
}
}
Any help with the recursive toFullString method will be greatly appreciated.
There are two levels you need to think about when designing a recursive solution.
How do I deal with the current item in the recursion?
How do I go from this item to the next one, and what information gets passed on?
Since we are printing out each item in the tree, there is going to be a single print statement inside of each recursive call. However, the string printed in each row includes information about previous steps that were traversed to reach the current node. How do we deal with this information? It needs to be passed down from previous recursive calls to the next one.
Here is a set of possible rules:
If the current item is a leaf, print out the current result.
If the current item has a left node, add <, and recursively act on the left node.
If the current item has a right node, add >, and recursively act on the right node.
What do we add < and > to? We need a parameter to carry along the current previous steps that have occurred in the recursion from recursive call to call. You don't want to simply print out < and > as you traverse the tree, because you need to remember the current set of steps to print out the prefix to every single node. There could be a second helper method that takes the same parameters as the original toFullString(), but a custom third parameter to carry the current set of previous steps.
So the logic might look something like this:
If there is no current prefix, initialize prefix to "", since the root initially has no steps to reach it.
If the current node is a leaf, add a line of output with the current prefix + leaf value.
If the current node has a left node, recursively call toFullString() on the left node, and add < to the current prefix string, which is handed down.
If the current node has a right node, recursively call toFullString() on the right node, and add > to the current prefix string, which is handed down.