Binary search tree and in-order traversal - java

I am trying to quickly implement a Binary search tree in Java. What is the best class to use that has methods for in-order traversal?
(I have heard of TreeMap class. But it looks like the class does not contain any methods to do in-order traversal).

Use LinkedHashMap to traverse in insertion order or TreeMap to traverse in comparison order
http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html

You could always just make your own class and that implements the algo using said class.
public class Node {
Node leftChild;
Node rightChild;
int parent;
Node(int parent) {
this.parent = parent;
}
}
And then implement the Binary Search Tree class. This was made very fast, but it's to give you an idea.
public class BSTree {
Node root;
BSTree() {
root = null;
}
public void insert(Node node, int value) {
if (value >= node.parent) {
if (!(node.rightChild == null)) {
insert(node.rightChild, value);
} else {
node.rightChild = new Node(value);
}
} else if (value < node.parent) {
if (!(node.leftChild == null)) {
insert(node.leftChild, value);
} else {
node.leftChild = new Node(value);
}
} else {
root = new Node(value);
}
}
public boolean delete(Node node, int value) {
if (root == null) {
return false;
} else if (value > root.parent) {
return delete(root.rightChild, value);
} else if (value < root.parent) {
return delete(root.leftChild, value);
} else {
if (root.leftChild == null && root.rightChild == null) {
root = null;
return true;
} else if (root.leftChild == null && root.rightChild != null) {
root = root.rightChild;
return true;
} else if (root.leftChild != null && root.rightChild == null) {
root = root.leftChild;
return true;
} else {
Node minRight = minNode(root.rightChild);
root = minRight;
delete(minRight, minRight.parent);
return true;
}
}
}
public Node minNode(Node node) {
if (node.leftChild == null) {
return node;
} else {
return minNode(node.leftChild);
}
}
}

The TreeSet class might be what you want
class Node implements Comparable<Node>; // implements your Node class
TreeSet<Node> set = new TreeSet<Node>();
// after adding a bunch of nodes into set
Iterator<Node> it = set.iterator();
while(it.hasNext()){
Node current = it.next();
System.out.println(current); // operate on current node
}
Node first = set.first(); // smallest element in set
Node second = set.ceiling(first); // the successor method

Related

Rebalancing a Binary Tree Using Array Recursively (Java)

I am trying to balance a binary tree recursively by adding the tree data into an array in order, balance that data/ nodes (to minimize height) then insert the now balanced data back into the tree in the correct order. I am stuck on how to correctly do this all recursively. Here is the code if you scroll down you will see rebalance along with the methods I made to attempt to balance this tree:
package adts;
import java.util.Stack;
import interfaces.*;
import nodes.BSTNode;
public class BinarySearchTree<T extends Comparable<T>>
implements BSTInterface<T>
{
protected BSTNode<T> root; // reference to the root of this BST
boolean found; // used by remove
// for traversals
protected ArrayQueue<T> inOrderQ;
protected ArrayQueue<T> preOrderQ;
protected ArrayQueue<T> postOrderQ;
protected BinarySearchTree left = null;
protected BinarySearchTree right = null;
protected T[] rebalanceArray;
public BinarySearchTree() {
root = null;
}
public void add (T element) {
root = recAdd(element, root);
}
private BSTNode<T> recAdd(T element, BSTNode<T> tree) {
if (tree == null) {
tree = new BSTNode<T>(element);
}
else {
if (element.compareTo(tree.getData()) <= 0) {
tree.setLeft(recAdd(element, tree.getLeft())); // add to left subtree
}
else {
tree.setRight(recAdd(element, tree.getRight())); // add to right subtree
}
}
return tree;
}
public boolean remove (T element) {
root = recRemove(element, root);
return found;
}
private BSTNode<T> recRemove(T element, BSTNode<T> tree) {
if (tree == null) {
found = false;
}
else {
if (element.compareTo(tree.getData()) < 0) {
tree.setLeft(recRemove(element, tree.getLeft()));
}
else {
if (element.compareTo(tree.getData()) > 0) {
tree.setRight(recRemove(element, tree.getRight()));
}
else {
tree = removeNode(tree);
found = true;
}
}
}
return tree;
}
private BSTNode<T> removeNode(BSTNode<T> tree) {
T payload;
if (tree.getLeft() == null) {
return tree.getRight();
}
else {
if (tree.getRight() == null) {
return tree.getLeft();
}
else {
payload = getPredecessor(tree.getLeft());
tree.setData(payload);
tree.setLeft(recRemove(payload, tree.getLeft()));
return tree;
}
}
}
private T getPredecessor(BSTNode<T> tree) {
while (tree.getRight() != null) {
tree = tree.getRight();
}
return tree.getData();
}
public int size() {
return recSize(root);
}
private int recSize(BSTNode<T> tree) {
if (tree == null) {
return 0;
}
else {
return recSize(tree.getLeft()) + recSize(tree.getRight()) + 1;
}
}
// this implementation of a size operation demonstrates that
// it is possible to visit all the nodes of the tree without recursion
public int size2() {
int count = 0;
if (root != null) {
LLStack<BSTNode<T>> hold = new LLStack<BSTNode<T>>();
BSTNode<T> currNode;
hold.push(root);
while (!hold.isEmpty()) {
currNode = hold.peek();
hold.pop();
count++;
if (currNode.getLeft() != null) {
hold.push(currNode.getLeft());
}
if (currNode.getRight() != null) {
hold.push(currNode.getRight());
}
}
}
return count;
}
public boolean isEmpty() {
return (root == null);
}
public boolean contains (T element) {
return recContains(element, root);
}
private boolean recContains(T element, BSTNode<T> tree) {
if (tree == null) return false;
else
if (element.compareTo(tree.getData()) < 0)
return recContains(element, tree.getLeft()); // search left subtree
else
if (element.compareTo(tree.getData()) > 0)
return recContains(element, tree.getRight()); // search right subtree
else
return true; // element is found!
}
public T get(T element) {
return recGet(element, root);
}
private T recGet(T element, BSTNode<T> tree) {
if (tree == null)
return null;
else
if (element.compareTo(tree.getData()) < 0)
return recGet(element, tree.getLeft()); // get from left subtree
else
if (element.compareTo(tree.getData()) > 0)
return recGet(element, tree.getRight()); // get from right subtree
else
return tree.getData(); // element is found!
}
public void rebalance() {
T[] rebalanceArray = (T[]) new Comparable[size()];
// I want to return the newly constructed/ balanced tree here
}
private BinarySearchTree constructBST(T[] rebalanceArray , int high, int low) {
if (low > high)
return null;
int mid = (low+high)/2;
BinarySearchTree node = new BinarySearchTree();
node.left = constructBST(rebalanceArray, low, mid - 1);
node.right = constructBST(rebalanceArray, mid + 1, high);
return node;
}
private void storeNodes(BSTNode<T> root, BinarySearchTree nodes) {
if(root == null)
return;
storeNodes(root.getLeft(), nodes);
nodes.add(root); //add function not working
storeNodes(root.getRight(), nodes);
}
// populate inOrderQ with tree elements based on in-order traversal
private void inOrder(BSTNode<T> tree) {
if (tree != null) {
inOrder(tree.getLeft());
inOrderQ.enqueue(tree.getData());
inOrder(tree.getRight());
}
}
// populate preOrderQ with tree elements based on pre-order traversal
private void preOrder(BSTNode<T> tree) {
if (tree != null) {
preOrderQ.enqueue(tree.getData());
preOrder(tree.getLeft());
preOrder(tree.getRight());
}
}
// populate postOrderQ with tree elements based on post-order traversal
private void postOrder(BSTNode<T> tree) {
if (tree != null) {
postOrder(tree.getLeft());
postOrder(tree.getRight());
postOrderQ.enqueue(tree.getData());
}
}
public int reset(TraversalType orderType) {
// returns current number of nodes in the tree
int numNodes = size();
switch (orderType) {
case INORDER :
inOrderQ = new ArrayQueue<T>(numNodes);
inOrder(root);
break;
case PREORDER :
preOrderQ = new ArrayQueue<T>(numNodes);
preOrder(root);
break;
case POSTORDER :
postOrderQ = new ArrayQueue<T>(numNodes);
postOrder(root);
break;
}
return numNodes;
}
public T getNext (TraversalType orderType) {
switch (orderType) {
case INORDER : return inOrderQ.dequeue();
case PREORDER : return preOrderQ.dequeue();
case POSTORDER: return postOrderQ.dequeue();
default: return null;
}
}
}
Here is the rebalance specific code:
public void rebalance() {
T[] rebalanceArray = (T[]) new Comparable[size()];
// I want to return the newly constructed/ balanced tree here
}
private BinarySearchTree constructBST(T[] rebalanceArray , int high, int low) {
if (low > high)
return null;
int mid = (low+high)/2;
BinarySearchTree node = new BinarySearchTree();
node.left = constructBST(rebalanceArray, low, mid - 1);
node.right = constructBST(rebalanceArray, mid + 1, high);
return node;
}
private void storeNodes(BSTNode<T> root, BinarySearchTree nodes) {
if(root == null)
return;
storeNodes(root.getLeft(), nodes);
nodes.add(root); //add function not working
storeNodes(root.getRight(), nodes);
}
input/ test tree:
package apps;
import adts.BinarySearchTree;
public class TestRUn800 {
public static void main(String[] args) {
BinarySearchTree<Integer> testTree1 = new BinarySearchTree<>();
testTree1.add(1);
testTree1.add(2);
testTree1.add(3);
testTree1.add(4);
testTree1.add(5);
testTree1.add(6);
testTree1.add(7);
System.out.println(testTree1.treeHeight() + " tree height");
System.out.println(testTree1.reckonUnbalanced() + " reckonUnbalanced Value");
System.out.print(testTree1.rebalance()); // rebalance statement
}
}
I did a lot of searching around on the web and saw some solutions that had a method that built the tree and stored it's data before then returning it in the original (rebalance()) method. That is what I have here in storeNodes and buildBST but cannot get it running correctly without errors. The error I am running into for add is "The method add(Comparable) in the type BinarySearchTree is not applicable for the arguments (BSTNode)" (I also commented next to add in the code so one can see where it is). Also as seen in the tree I find tree height, the unbalanced height (reckonUnbalanced) then I want to rebalance it and get it's new height (I have not written that code in this example though just what I plan to do once I get the actual code working for rebalance).

Comparing two valus of Nodes in Binary search trees in java

hey I am new in the binary trees world and I am trying to compare to values to know which direction should I place the newly added node next.
for now, I tried to do CompareTo method but didn't succeed very much I am now trying to make a private method that will give me the value of the Nodes i would love some help
this is my code now I need to add to the if statement the comparing of nodes so I can proceed :
public void add(E data) {
if(root == null) {
return ;
}
if(root.getLeftSon() == null) {
root.setLeftSon((Node<E>) data);
}
else if(root.getRightSon() == null) {
root.setRightSon((Node<E>) data);
}
}
you have to use generics correctly. Parameter has to extend comparable so you can determinate how to sort it.
class BinaryTree<T extends Comparable<T>> {
Node<T> root;
public Node<T> addRecursive(Node<T> current, T value) {
if (current == null) {
return new Node<T>(value);
}
int ord = value.compareTo(current.value);
if (ord > 0) {
current.left = addRecursive(current.left, value);
} else if (ord < 0) {
current.right = addRecursive(current.right, value);
} else {
// value already exists
return current;
}
return current;
}
static class Node<T extends Comparable<T>> {
T value;
Node<T> left;
Node<T> right;
Node(T value) {
this.value = value;
right = null;
left = null;
}
}
}

Is my Binary Tree adding nodes properly?

I've just created a method to test the height of my binary tree implementation as follows:
public int height() {
return height(rootNode);
}
private int height(BinaryTreeNode node) {
if(node == null) return -1;
else return 1 + Math.max(height(node.getLeftChild()), height(node.getRightChild()));
}
But it returns a height of 6, and not 7 when i add the nodes 1-6.
Here is my Binary Tree code:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
public class BinaryTree<E extends Comparable<E>>
{
private class BinaryTreeNode
{
private E value;
private BinaryTreeNode leftChild, rightChild;
public BinaryTreeNode(E value) {
this(value, null, null);
}
public BinaryTreeNode(E value, BinaryTreeNode leftChild, BinaryTreeNode rightChild) {
this.value = value;
this.leftChild = leftChild;
this.rightChild = rightChild;
}
public E getValue() {
return value;
}
public BinaryTreeNode getLeftChild() {
return leftChild;
}
public BinaryTreeNode getRightChild() {
return rightChild;
}
public void setLeftChild(BinaryTreeNode newLeftChild) {
this.leftChild = newLeftChild;
}
public void setRightChild(BinaryTreeNode newRightChild) {
this.rightChild = newRightChild;
}
}
private BinaryTreeNode rootNode;
public BinaryTree() {
this.rootNode = null;
}
public void addNode(E value) {
if(rootNode == null)
rootNode = new BinaryTreeNode(value);
else
addNode(value, rootNode);
}
//TODO: Implement removeNode()
public void printLevelOrder() {
printLevelOrder(rootNode);
}
public int height() {
return height(rootNode);
}
public void inOrderTraversal() {
if(rootNode != null) inOrderTraversal(rootNode);
else System.out.println("The tree is empty!");
}
private void addNode(E value, BinaryTreeNode node) {
if(node.getValue().compareTo(value) > 0) {
if(node.getLeftChild() != null)
addNode(value, node.getLeftChild());
else
node.setLeftChild(new BinaryTreeNode(value));
} else {
if(node.getRightChild() != null)
addNode(value, node.getRightChild());
else
node.setRightChild(new BinaryTreeNode(value));
}
}
private void printLevelOrder(BinaryTreeNode node) {
Queue<BinaryTreeNode> currentLevel = new LinkedList<BinaryTreeNode>();
Queue<BinaryTreeNode> nextLevel = new LinkedList<BinaryTreeNode>();
currentLevel.add(node);
while (!currentLevel.isEmpty()) {
Iterator<BinaryTreeNode> iter = currentLevel.iterator();
while (iter.hasNext()) {
BinaryTreeNode currentNode = iter.next();
if (currentNode.leftChild != null) {
nextLevel.add(currentNode.leftChild);
}
if (currentNode.rightChild != null) {
nextLevel.add(currentNode.rightChild);
}
System.out.print(currentNode.value + " ");
}
System.out.println();
currentLevel = nextLevel;
nextLevel = new LinkedList<BinaryTreeNode>();
}
}
private int height(BinaryTreeNode node) {
if(node == null) return -1;
else return 1 + Math.max(height(node.getLeftChild()), height(node.getRightChild()));
}
private void inOrderTraversal(BinaryTreeNode node) {
if(node != null) {
inOrderTraversal(node.leftChild);
System.out.println(node.getValue() + " ");
inOrderTraversal(node.getRightChild());
}
}
public BinaryTreeNode getRoot() {
return rootNode;
}
}
I think the problem is adding my node into the tree, but I've taken a look at other examples but they all seem to be doing the same thing I am.. So i can't realise the problem!
Thanks!
private int height(BinaryTreeNode node) {
if(node == null) return 0;
else return 1 + Math.max(height(node.getLeftChild()), height(node.getRightChild()));
}
You were returning -1 on node==null when you should return 0.
The condition is true when we arrive to leaf so for example if we add 1-2 then we have height as 1+Max(leftof(1),rightof(1))=
1+Max(height(null),height(2))=
1+Max(0,1+Max(leftof(2),rightof(2)))=
1+Max(0,1+Max(height(null),height(null)))=
1+Max(0,1+Max(0,0))=
1+Max(0,1+0)=
1+1=2.
Try to replace height(null) with -1 in the previous example to see by yourself.
By the way your BinaryTree implementation is actually a binary search tree since you're putting less elements on the left and bigger elements on the right, If a search tree is your intention then Ok but if you want to implement a general binary tree then you should change the add function.

Binary Search Tree insertion - root remains null

I'm new to Java, I want to create a Binary Search Tree class with insertion and preorder traversal, but when I finish the insertion the root object remains null and the compiler throws NullPointerException during the preorder traversal.
My node class:
class Node {
int info;
Node left;
Node right;
public Node() {
info = 0;
left = null;
right = null;
}
Node(int x) {
info = x;
left = null;
right = null;
}
}
My Binary Search Tree class:
public class BinarySearchTree {
private Node root;
public BinarySearchTree() {
root = null;
}
private void insertPrivate(Node node, int x) {
if(node == null) {
node = new Node(x);
}
else {
if(x < node.info) {
insertPrivate(node.left, x);
}
else if (x > node.info) {
insertPrivate(node.right, x);
}
}
}
public void insert(int x) {
insertPrivate(root, x);
}
private void preorderPrivate(Node node) {
if(node != null) {
System.out.println(node.info);
preorderPrivate(node.left);
preorderPrivate(node.right);
}
}
public void preorder() {
preorderPrivate(root);
}
public static void main(String[] args) {
BinarySearchTree t = new BinarySearchTree();
t.insert(12);
t.insert(13);
t.preorder();
}
}
The issue is a misunderstanding of Java referencing as seen with this section of code.
private void insertPrivate(Node node, int x) {
if(node == null) {
node = new Node(x);
}
....
Java references are passed by value into function arguments.
Let me give you an example to clarify.
Node root = new Node(x);
// root == Node(x);
doSomething(root);
// Pass Node(x) into function;
void doSomething(Node node) {
// root == Node(x);
// node == Node(x);
node = new Node(y); // This updates node but not root
// root == Node(x);
// node == Node(y);
}
You are going to have to restructure your program. One way would be to have insertPrivate return a Node and assign that value to root. It is not the most efficient but it will work.
public void insert(int x) {
root = insertPrivate(root, x);
}
private Node insertPrivate(Node node, int x) {
if(node == null) {
node = new Node(x);
}
else {
if(x < node.info) {
node.left = insertPrivate(node.left, x);
}
else if (x > node.info) {
node.right = insertPrivate(node.right, x);
}
}
return node;
}
Change insert(int x) like this:
public void insert(int x) {
if (root == nul)
root = new Node(x);
else
insertPrivate(root, x);
}
Try :
Node left = new Node();
Node right = new Node();
You should somehow return the newly created node and assign it to the left or right node of the parent. Try this:
private Node insertPrivate(Node node, int x) {
if(node == null) {
node = new Node(x);
}
else {
if(x < node.info) {
node.left = insertPrivate(node.left, x);
}
else if (x > node.info) {
node.right = insertPrivate(node.right, x);
}
}
return node;
}
And your public insert function should be:
public void insert(int x) {
root = insertPrivate(root, x);
}
Also preorderPrivate needs a null-checking:
private void preorderPrivate(Node node) {
System.out.println(node.info);
if (node.left != null)
preorderPrivate(node.left);
if (node.right != null)
preorderPrivate(node.right);
}

Insert node into binary search tree

I have been plugging away at a Binary Search Tree implementation for a few days now and I am to the point where I know that my root is being populated through the use of my 'insert()' (I can see this when I debug, using Eclipse). Why won't my other nodes get added to the tree?
Here is my BST Class:
package binarySearchTree;
public class BinarySearchTree<T extends Comparable<T>> {
#SuppressWarnings("hiding")
private class BinarySearchTreeNode<T>{
public BinarySearchTreeNode left, right;
private T data; //LINE 8
private BinarySearchTreeNode (T data,BinarySearchTreeNode left, BinarySearchTreeNode right ) {
this.left = left;
this.right = right;
this.data = data;
}
}
private BinarySearchTreeNode<T> root;
#SuppressWarnings("unused")
private T search(T target, BinarySearchTreeNode<T> ptr) {
//find target in subtree A ptr
if (root == null || ptr == null) {
return root; //target is not in tree
}
int compare = target.compareTo(ptr.data); //compareTo(ptr.data);
if (compare == 0) {
return ptr.data; //target is found
}
if (compare < 0) {
return search(target, ptr.left);
}
if (compare > 0) {
return search(target, ptr.right);
}
return target;
}
public T search(T target) {
return search(target);
}
public boolean isEmpty() {
return root == null;
}
/* To insert a data into a BST, 1st search for the data,
* if the data is found = duplicate data error
* if the data is NOT found = a null pointer
* Make this null pointer point to a NewNode holding data
* new values go into the BST as leaves
* Using public boolean insert (T node) &
* private boolean insert (T Node, BSTNode<T> ptr) as a recursive method
*/
#SuppressWarnings("unchecked")
private boolean insert(T value, BinarySearchTreeNode<T> ptr) {
//T data = null;
//insert data in a child of ptr, return false if duplicate is found
//Precondition: ptr must not be null
int compare = value.compareTo(ptr.data); //LINE 55
if (compare == 0) {
return false;
}
if (compare < 0) {
if (ptr.left == null) {
//found insertion point
BinarySearchTreeNode<T> node = new BinarySearchTreeNode<>(value, null, null);
ptr.left.data = node; //insert data in new node
return true;
}
} else {
return insert(value, ptr.left); //LINE 67
}
if (compare > 0) {
if (ptr.right == null) {
BinarySearchTreeNode<T> node = new BinarySearchTreeNode<>(value, null, null);
ptr.right.data = node;
return true;
} else {
return insert(value, ptr.right);
}
}
return false;
}
public boolean insert(T value) {
if (isEmpty()) {
root = new BinarySearchTreeNode<T>(value, null, null);
return true;
}
return insert(value, root); // LINE 85
}
}
And here is my Main(), eventually I would like to print the values of my BST in the console but first I know they need to be added to the tree:
package binarySearchTree;
public class Main {
public static void main(String[] args) {
BinarySearchTree<String> bstStrings = new BinarySearchTree<String>();
String s = "Hello";
String s1 = "World";
//String s2 = "This Morning";
bstStrings.insert(s);
bstStrings.insert(s1); //LINE 15
//bstStrings.insert(s2);
while (true){
if (!bstStrings.isEmpty()){
System.out.println(bstStrings + " ");
}
System.out.println();
System.out.println("You should have values above this line!");break;
}
}
}
Your root should be of BinarySearchTree<T> and not T
As a result you are not storing the values in the subtrees of the root.
Replace this:
return insert((T) value, node);
with
return insert((T) value, root);
in your code replace as follows:
public boolean insert(T value) {
if (isEmpty()) {
root = new BinarySearchTreeNode((T) value, null, null);
return true;
}
return insert((T) value, root); // start recursion
}
Otherwise you don't have a tree and the nodes are not linked to each other
UPDATE:
You get the NPE because you pass in insert the left child of root in the first comparison which is null.
You should not return boolean but BinarySearchTreeNode.
Your method should be:
#SuppressWarnings("unchecked")
private BinarySearchTreeNode<T> insert(T value, BinarySearchTreeNode<T> ptr) {
if(ptr == null){
ptr = new BinarySearchTreeNode<T>(value,null,null);
return ptr;
}
//your code next but return the `ptr`
}
Then in insert you should do:
public void insert(T value) {
root = insert(value, root);
}
After the first insertion, you create new nodes, but don't do anything with them.

Categories