I am learning about Binary Search Tree and working on a project. When I tried to delete the first node I inserted, it doesn't delete and still show that node when I call showAll method. Is that how Binary Search Tree works or did I do something incorrectly?
Thanks,
Here is the code for BinarySearchTree class:
public class BinarySearchTree_Pham {
TreeNode root;
public BinarySearchTree_Pham() {
root = null;
}
public boolean insert(Student_Pham newStudent) {
TreeNodeWrapper p = new TreeNodeWrapper();
TreeNodeWrapper c = new TreeNodeWrapper();
TreeNode n = new TreeNode();
if(n == null)
return false;
else {
n.node = newStudent.deepCopy();
n.lc = null;
n.rc = null;
if(root == null) {
root = n;
}
else {
findNode(newStudent.getId(), p, c);
if(newStudent.getId().compareTo(p.get().node.getId()) < 0)
p.get().lc = n;
else
p.get().rc = n;
}
return true;
}
} //end insert
public Student_Pham fetch(String id) {
boolean found;
TreeNodeWrapper p = new TreeNodeWrapper();
TreeNodeWrapper c = new TreeNodeWrapper();
found = findNode(id, p, c);
if (found == true)
return c.get().node.deepCopy();
else
return null;
} //end fetch
public boolean delete(String id) {
boolean found;
TreeNodeWrapper p = new TreeNodeWrapper();
TreeNodeWrapper c = new TreeNodeWrapper();
TreeNode largest;
TreeNode nextLargest;
found = findNode(id, p, c);
if(found == false)
return false;
else {
if(c.get().lc == null && c.get().rc == null) {
if (p.get().lc == c.get())
p.get().lc = null;
else
p.get().rc = null;
} //end case 1
else if (c.get().lc == null || c.get().rc == null) {
if (p.get().lc == c.get()) {
if (c.get().lc != null)
p.get().lc = c.get().lc;
else
p.get().lc = c.get().rc;
}
else {
if (c.get().lc != null)
p.get().rc = c.get().lc;
else
p.get().rc = c.get().rc;
}
} // end case 2
else {
nextLargest = c.get().lc;
largest = nextLargest.rc;
if (largest != null) {
while (largest.rc != null) {
nextLargest = largest;
largest = largest.rc;
}
c.get().node = largest.node;
nextLargest.rc = largest.lc;
}
else {
nextLargest.rc = c.get().rc;
if (p.get().lc == c.get())
p.get().lc =nextLargest;
else
p.get().rc = nextLargest;
}
} // end case 3
return true;
}
} // end of delete
public boolean update(String id, Student_Pham newStudent) {
if(delete(id) == false)
return false;
else if (insert(newStudent) == false)
return false;
return true;
} // end update
public void showAll() {
if (root == null)
System.out.println("Structure is empty.");
else
LNRoutputTraversal(root);
} //end showAll
private void LNRoutputTraversal(TreeNode root) {
if (root.lc != null)
LNRoutputTraversal(root.lc);
System.out.println(root.node);
if (root.rc != null)
LNRoutputTraversal(root.rc);
}
public class TreeNode {
private Student_Pham node;
private TreeNode lc;
private TreeNode rc;
public TreeNode() {}
}
private boolean findNode(String targetKey, TreeNodeWrapper parent, TreeNodeWrapper child) {
parent.set(root);
child.set(root);
if (root == null)
return true;
while (child.get() != null) {
if(child.get().node.getId().compareTo(targetKey) == 0)
return true;
else {
parent.set(child.get());
if(targetKey.compareTo(child.get().node.getId()) < 0)
child.set(child.get().lc);
else
child.set(child.get().rc);
}
} //end while
return false;
}
public class TreeNodeWrapper {
TreeNode treeRef = null;
public TreeNodeWrapper() {}
public TreeNode get() {return treeRef;}
public void set(TreeNode t) {treeRef = t;}
}
}
Related
I have a method that tests if a binary search tree is an AVL tree, and am not getting the results i want.
here is the code :fg(left child) - fd(right child) - ag(left tree) - Noeud(node) - racine(root)
package cm5_TP_algo;
class Noeud {
int height;
int v;
Noeud fg;
Noeud fd;
Noeud(Noeud fg,int v,Noeud fd){
this.fg=fg;
this.v=v;
this.fd=fd;
}
public String toString(){
String sb = "[";
if (fg!=null)sb += fg.toString();
sb += v;
if (fd!=null)sb += fd.toString();
return sb + "]";
}
boolean testABR(int min, int max) {
if (fg != null && !fg.testABR(min, v)) {
return false;
}
if (fd != null && !fd.testABR(v, max)) {
return false;
}
return v >= min && v <= max;
}
public int calculateHeight() {
int heightLeft = (fg == null) ? 0 : fg.calculateHeight();
int heightRight = (fd == null) ? 0 : fd.calculateHeight();
height = Math.max(heightLeft, heightRight) + 1;
return height;
}
}
public class Arbre {
Noeud racine;
public Arbre(){ racine=null;}
public Arbre(Arbre ag, int v, Arbre ad) {
racine = new Noeud (ag.racine, v, ad.racine);
}
public String toString() {
if (racine == null) { return ""; }
else { return racine.toString(); }
}
public boolean testABR() {
return racine == null || racine.testABR(Integer.MIN_VALUE, Integer.MAX_VALUE);
}
public void inser(int value){
if(racine == null)
racine = new Noeud(null, value, null);
else{
inser(value, racine);
}
}
public void inser(int value, Noeud racine){
if ( racine.v > value && racine.fg == null ) {
racine.fg = new Noeud(null, value, null);
return;
}
else if(racine.v > value && racine.fg != null){
inser(value, racine.fg);
}
if (racine.v < value && racine.fd == null ) {
racine.fd = new Noeud(null, value, null);
return;
}
else if(racine.v < value && racine.fd != null) {
inser(value, racine.fd);
}
}
public boolean membre(int value) {
if(racine == null)
return false;
if(racine.v == value)
return true;
if(racine.v < value && racine.fd != null )
return membre(value, racine.fd);
if(racine.v > value && racine.fg != null)
return membre(value, racine.fg);
return false;
}
private boolean membre(int value, Noeud racine) {
if(racine.v == value)
return true;
if(racine.v < value && racine.fd != null )
return membre(value, racine.fd);
if(racine.v > value && racine.fg != null)
return membre(value, racine.fg);
return false;
}
public void updateHeights() {
if (racine != null) {
racine.calculateHeight();
}
}
private int getHeight(Noeud noeud) {
if (noeud == null) {
return -1;
}
return noeud.height;
}
public boolean testAVL() {
updateHeights();
return checkBalanced();
}
private boolean checkBalanced() {
return checkBalanced(this.racine);
}
private boolean checkBalanced(Noeud node) {
if (node == null) return true;
int balance = getHeight(node.fd) - getHeight(node.fg);
if (Math.abs(balance) > 1) {return false;}
return checkBalanced(node.fd) && checkBalanced(node.fg);
}
public static void main(String[] args) {
Arbre t1= new Arbre( new Arbre() ,1, new Arbre() );
Arbre t2= new Arbre(
new Arbre(
new Arbre( )
, 12,
new Arbre( ))
, 13,
new Arbre() );
Arbre t3= new Arbre( t1,15,t2);
Arbre t4= new Arbre( t2,16,t3);
System.out.println(t1+":"+t1.testAVL());
System.out.println(t2+":"+t2.testAVL());
System.out.println(t3+":"+t3.testAVL());
System.out.println(t4+":"+t4.testAVL());
}
}
The expected result is :
[[12]13]:true
[115[[12]13]]:false
[[[12]13]16[115[[12]13]]]:false
But what i get is :
[[12]13]:false
[115[[12]13]]:false
[[[12]13]16[115[[12]13]]]:false
Is the problem with the testAVL or the updateHeights ?
I'm currently struggling to write a union() method for my AVL (auto balancing) tree IntegerSet Class.
Some requirements for my class:
Integer sets are ordered
Methods must be at most O(NlogN) time
You may not use a built in tree Java library. You must implement your own tree
The union() method: This is the mathematical union on two sets which creates a new set that contains all the elements from both sets. For example, [1, 2, 3] U [2, 3, 5, 6] results in a new set [1, 2, 3, 5, 6].
My thought was to copy the unique elements of each tree into an array, then use my constructor to create a new tree from that array. However, I haven't been able to copy the elements into an array correctly. I'm also wondering if there's a better way to be doing this.
My current code is below:
package dataStructures.AVL;
import java.util.LinkedList;
import java.util.Queue;
public class IntegerSet {
private Node root;
private int size;
public IntegerSet() {
clear();
}
public IntegerSet(int array[]) {
// Add elements of array to Binary Search Tree
for (int i = 0; i < array.length; i++) {
add(array[i]);
}
}
public int magnitude() {
return size;
}
public void clear() {
root = null;
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public boolean add(int newItem) {
boolean added = false;
if (isEmpty()) {
root = new Node(newItem);
size += 1;
added = true;
} else {
added = add(null, root, newItem);
}
return added;
}
private boolean add(Node parent, Node current, int data) {
boolean added = false;
if (current == null) {
int result = data - parent.data; // data.compareTo(parent.data);
if (result < 0) {
parent.leftChild = new Node(data);
} else {
parent.rightChild = new Node(data);
}
size += 1;
return true;
} else if ((data - current.data) < 0) { // (data.compareTo(current.data) < 0) {
added = add(current, current.leftChild, data);
} else if (data - current.data > 0) { // (data.compareTo(current.data) > 0) {
added = add(current, current.rightChild, data);
} else {
return false;
}
fixHeight(current);
if (added) {
rebalance(parent, current);
}
return added;
}
public boolean remove(int itemToRemove) {
if (isEmpty()) {
return false;
} else if (size == 1 && root.data == itemToRemove) { // (size == 1 && root.data.equals(itemToRemove)) {
clear();
return true;
} else if (removeTraversal(null, root, itemToRemove)) {
size -= 1;
return true;
} else {
return false;
}
}
private boolean removeTraversal(Node parent, Node current, int data) {
boolean removed = true;
if (current == null) {
return false;
} else if (data - current.data < 0) { // (data.compareTo(current.data) < 0) {
removed = removeTraversal(current, current.leftChild, data);
} else if (data - current.data > 0) { // (data.compareTo(current.data) > 0) {
removed = removeTraversal(current, current.rightChild, data);
} else {
removeNode(parent, current);
}
fixHeight(current);
if (removed) {
rebalance(parent, current);
}
return removed;
}
private void removeNode(Node parent, Node current) {
if (current.leftChild == null && current.rightChild == null) {
// Remove leaf node
removeCase1(parent, current);
} else if (current.leftChild != null && current.rightChild == null) {
// Remove node with no right child
removeCase2(parent, current);
} else if (current.leftChild == null && current.rightChild != null) {
// Remove node with no left child
removeCase3(parent, current);
} else {
// Remove node with both children
removeCase4(parent, current);
}
fixHeight(parent);
}
private void removeCase1(Node parent, Node current) {
if (parent == null) {
root = null;
} else if (parent.leftChild == current) {
parent.leftChild = null;
} else {
parent.rightChild = null;
}
}
private void removeCase2(Node parent, Node current) {
if (parent == null) {
root = root.leftChild;
} else if (parent.leftChild == current) {
parent.leftChild = current.leftChild;
} else {
parent.rightChild = current.leftChild;
}
current.leftChild = null;
}
private void removeCase3(Node parent, Node current) {
if (parent == null) {
root = root.rightChild;
} else if (parent.leftChild == current) {
parent.leftChild = current.rightChild;
} else {
parent.rightChild = current.rightChild;
}
current.rightChild = null;
}
private void removeCase4(Node parent, Node current) {
Node leftMost = current.rightChild;
Node leftMostParent = current;
while (leftMost.leftChild != null) {
leftMostParent = leftMost;
leftMost = leftMost.leftChild;
}
current.data = leftMost.data;
removeNode(leftMostParent, leftMost);
rebalance(current, current.rightChild);
}
public boolean contains(int itemToFind) {
if (isEmpty()) {
return false;
} else {
Node temp = root;
while (temp != null) {
int result = itemToFind - temp.data;
if (result < 0) {
temp = temp.leftChild;
} else if (result > 0) {
temp = temp.rightChild;
} else {
return true;
}
}
}
return false;
}
public IntegerSet union(IntegerSet other) {
return null;
}
public IntegerSet intersection(IntegerSet other) {
return null;
}
public IntegerSet difference(IntegerSet other) {
return null;
}
public IntegerSet symmetricDifference(IntegerSet other) {
return null;
}
public int getMin() {
if (isEmpty()) {
throw new EmptyCollectionException("Cannot remove from an empty tree.");
} else {
Node temp = root;
while (temp.leftChild != null) {
temp = temp.leftChild;
}
return temp.data;
}
}
public int getMax() {
if (isEmpty()) {
throw new EmptyCollectionException("Cannot remove from an empty tree.");
} else {
Node temp = root;
while (temp.rightChild != null) {
temp = temp.rightChild;
}
return temp.data;
}
}
public int getHeight() {
return getHeight(root);
}
private int getHeight(Node node) {
if (node == null) {
return -1;
}
return Math.max(node.leftHeight, node.rightHeight);
}
private void fixHeight(Node node) {
if (node != null) {
node.leftHeight = getHeight(node.leftChild) + 1;
node.rightHeight = getHeight(node.rightChild) + 1;
}
}
private int balance(Node node) {
// If the balance > 1 imbalance is in left subtree
// If the balance < -1 imbalance is in right subtree
return node.leftHeight - node.rightHeight;
}
private Node rightRotation(Node n) {
Node c = n.leftChild;
Node t2 = c.rightChild;
c.rightChild = n;
n.leftChild = t2;
fixHeight(n);
fixHeight(c);
return c;
}
private Node leftRotation(Node n) {
Node c = n.rightChild;
Node t2 = c.leftChild;
c.leftChild = n;
n.rightChild = t2;
fixHeight(n);
fixHeight(c);
return c;
}
private void rebalance(Node parent, Node node) {
if (node == null) {
return;
}
// Imbalance in left subtree
if (balance(node) > 1) {
// Handles case III
if (balance(node.leftChild) < 0) {
// leftRotation
node.leftChild = leftRotation(node.leftChild);
}
if (parent == null) {
root = rightRotation(node);
} else if (parent.leftChild == node) {
parent.leftChild = rightRotation(node);
} else {
parent.rightChild = rightRotation(node);
}
// Imbalance in right subtree
} else if (balance(node) < -1) {
// Handle case IV
if (balance(node.rightChild) > 0) {
node.rightChild = rightRotation(node.rightChild);
}
if (parent == null) {
root = leftRotation(node);
} else if (parent.leftChild == node) {
parent.leftChild = leftRotation(node);
} else {
parent.rightChild = leftRotation(node);
}
}
}
#Override
public String toString() {
return levelOrderString();
}
public String levelOrderString() {
StringBuffer sb = new StringBuffer();
sb.append("{");
if (!isEmpty()) {
Queue<Node> q = new LinkedList<>();
q.add(root);
Node current = null;
while (!q.isEmpty()) {
current = q.remove();
if (current.leftChild != null) {
q.add(current.leftChild);
}
if (current.rightChild != null) {
q.add(current.rightChild);
}
sb.append(current);
if (!q.isEmpty()) {
sb.append(", ");
}
}
}
sb.append("}");
return sb.toString();
}
public String inOrderToString() {
StringBuffer sb = new StringBuffer();
sb.append("{ ");
inOrderToString(root, sb);
sb.append(" }");
return sb.toString();
}
private void inOrderToString(Node current, StringBuffer sb) {
if (current != null) {
inOrderToString(current.leftChild, sb);
if (current.leftChild != null) {
sb.append(", ");
}
sb.append(current.data);
if (current.rightChild != null) {
sb.append(", ");
}
inOrderToString(current.rightChild, sb);
}
}
// You may add any methods or constructors
// to this class that you see fit.
private class Node {
private int data;
private Node leftChild;
private Node rightChild;
private int leftHeight;
private int rightHeight;
public Node(int data) {
this.data = data;
}
public String toString() {
String formatter = "(%s | %s | %s)";
String leftString = leftChild != null ? Integer.toString(leftChild.data) : "";
String rightString = rightChild != null ? Integer.toString(rightChild.data) : "";
return String.format(formatter, Integer.toString(data), leftString, rightString);
}
}
}
My removal method consists of 4 if statements that tackle the 4 different kinds of removal in a binary search tree. Not sure where wrong but it didn't remove any node when I check it. Any help if appreciated. Thanks in advance'
I suspect the problems lies in are where I try to replace the node removal to be null
public class BinaryTree<T extends Comparable<T>> {
private class Node{
private T data;
private Node left;
private Node right;
// left and right child do not have to nessary exist
public Node ( T data) {
this.data = data;
this.left = null;
this.right = null;
}}
private Node root;
private int count = 0;
public void add( T data) {
if ( isEmpty()) {
root = new Node(data);
count++;
}
else {
insert(data, root);
count++;
}
}
public boolean isEmpty() {
return root == null;
}
public T getRoot() {
if ( root.data == null) {
System.out.println("Root is empty");
return null;
}
else {
return root.data;
}}
public Node getRootNode() {
return root;
}
/*
* Checking if the data is larger or lesser than the parent's data
* If the data is smaller than the parent's data, node.left is created
* If the data is bigger than the parent's data, node.right is created
*/
private void insert( T data, Node node) {
/*
* If 1st obj is less than the 2nd obj return a neg
* if 1st obj is more than the 2nd obj return a pos
* if equal return 0
*/
int compare = data.compareTo(node.data);
if ( compare < 1 ){
if (node.left == null ) {
node.left = new Node(data);
}
// make node.left if it is filled
else {
insert(data, node.left);
}
}
else {
if ( node.right == null) {
node.right = new Node(data);
}
else {
insert( data, node.right);
}
}
}
public int getSize() {
return count;
}
public boolean search ( T data) {
Node temp = searchInner(data, root);
if ( temp.data == data) {
System.out.println(temp.data);
return true;
}
else {
return false;
}
}
public Node searchInner( T data, Node node) {
int compare = data.compareTo(node.data);
if ( getRoot() == data ) {
return root;
}
if ( compare > 0) {
return searchInner( data, node.right);
}
if ( compare < 0 ) {
return searchInner(data , node.left);
}
if ( compare == 0 ) {
return node;
}
else {
System.out.println("Not found");
return node;
}
}
public void remove( T data) {
remove1( root, data);
}
private Node remove1( Node node1, T data) {
Node parent = root;
Node node = root;
Node temp;
boolean isLeft = true;
while ( node.data != data) {
parent = node;
if ( isEmpty()) {
System.out.println("Unable to remove, root is empty");
break;
}
if ( compare(data, node.data) < 0) {
node = node.left;
isLeft = true;
}
if ( compare(data, node.data) > 0) {
node = node.right;
isLeft = false;
}
else {
// remove node if left child available
if ( node.left == null && node.right != null) {
if ( isLeft) {
parent.left = node.right;
}
else {
parent.right = node.right;
}
count --;
break;
}
//remove node if right child available
if ( node.right == null && node.left != null) {
if ( isLeft) {
parent.left = node.left;
}
else {
parent.right = node.left;
}
count --;
break;
}
// Remove node if 2 child available
if ( node.left != null && node.right != null ) {
node = min(node.right);
node.right = remove1(node.right, node.data);
}
// remove node if no child available
if ( node.left == null && node.right == null) {
if ( isLeft ) {
parent.left = null;
}
else {
parent.right = null;
}
count --;
break;
}
}
}
return node;
}
// fine the smallest node in the right subtree
private Node min ( Node node1 ) {
while ( node1.left != null) {
node1 = node1.left;
}
return node1;
}
private int compare( T data, T data1) {
return data.compareTo(data1);
}
public void printBST(T data) {
printTree( root, data);
}
private void printTree( Node node, T data)
{
if(node == null) return;
System.out.println(data + " + " + node.data);
printTree(node.left , data);
printTree(node.right , data);
}
public int getHeight() {
return height(root);
}
private int height( Node node) {
if (node == null) return 0;
else
return 1 + Math.max(height(node.left), height(node.right));
}
public void print() {
println(root);
}
private void println ( Node node) {
LinkedList<T> q = new LinkedList<T>();
q.add(node.data);
if ( node == null) {
return;
}
int size = getSize();
while ( size > 0) {
System.out.print(q);
q.clear();
if ( node.left != null) {
q.add(node.left.data);
size --;
}
if ( node.right != null) {
q.add(node.right.data);
size --;
}
if ( node.right != null&& node.left != null) {
System.out.println();
}
if ( size > 1) {
System.out.println(",");
}
}
}
public boolean sameTree( Node root1, Node root2) {
if ( root1 == null && root2 == null) {
return true;
}
if ( root1 != null && root2 != null) {
return root1.data == root2.data && sameTree(root1.left,root2.left) && sameTree(root1.right, root2.right);
}
else {
return false;
}
}
}
I have rewritten your BinaryTree class. I have added a new remove method, which uses your min(Node node) method and other one I have created, that only removes the minimum element of the tree. In addition, I have modified your Node class too by adding a new constructor and added your size variable that was in BinaryTree class
I have modified all of this in order to make the method remove() working properly
import java.util.LinkedList;
public class BinaryTree<T extends Comparable<T>> {
private class Node<T> { //Here we specify what the node contains
private T data;
private Node<T> left;
private Node<T> right;
private int size;
public Node(T value) {
this(value, null, null);
}
// left and right child do not have to nessary exist
public Node(T data, Node<T> left, Node<T> right) {
this.data = data;
this.left = null;
this.right = null;
size = 1;
if (left != null) {
size += left.size;
}
if (right != null) {
size += right.size;
}
}
}
private Node root;
public BinaryTree() { //Added a constructor to set the root node to null
root = null;
}
public boolean isEmpty() {
return root == null;
}
public T getRootData() { //Changed the name to other more clear
if (root.data == null) {
System.out.println("Root is empty");
return null;
} else {
return (T) root.data;
}
}
public Node getRootNode() {
return root;
}
public void insert(T x) { //The new insert method
root = insert(x, root);
}
protected Node<T> insert(T x, Node<T> actual) {
//We check if the node exists, in case not we just create a new node
if (actual == null) {
return new Node<T>(x);
}
int cmp = compare(x, actual.data);
if (cmp < 0) {
actual.left = insert(x, actual.left);
} else if (cmp > 0) {
actual.right = insert(x, actual.right);
} else {
// If the node exists we just update his content
actual.data = x;
}
actual.size = 1 + getSize(actual.left) + getSize(actual.right);
return actual;
}
public int getSize() { //New method
return getSize(root);
}
private int getSize(Node<T> actual) {
if (actual == null) {
return 0;
} else {
return actual.size;
}
}
public boolean search(T data) {
Node temp = searchInner(data, root);
if (temp.data == data) {
System.out.println(temp.data);
return true;
} else {
return false;
}
}
public Node searchInner(T data, Node node) {
int compare = data.compareTo((T) node.data);
if (getRootData() == data) {
return root;
}
if (compare > 0) {
return searchInner(data, node.right);
}
if (compare < 0) {
return searchInner(data, node.left);
}
if (compare == 0) {
return node;
} else {
System.out.println("Not found");
return node;
}
}
public void remove(T data) {
remove1(root, data);
}
private Node remove1(Node actual, T data) {
if (actual == null) {
return actual;
}
int cmp = compare(data, (T) actual.data);
//Check whether the value is lesser greater or equal than the one we are just visiting
if (cmp < 0) {
actual.left = remove1(actual.left, data);
} else if (cmp > 0) {
actual.right = remove1(actual.right, data);
} else {
if (actual.right == null) {
return actual.left;
}
if (actual.left == null) {
return actual.right;
}
actual.data = min(actual.right).data;
actual.right = removeMin(actual.right);
}
return actual;
}
public Node removeMin() {
//A new method to remove the minimum element
Node min = min(root);
root = removeMin(root);
return min;
}
private Node removeMin(Node actual) {
if (actual.left == null) {
return actual.right;
}
actual.left = removeMin(actual.left);
actual.size--;
return actual;
}
// fine the smallest node in the right subtree
private Node min(Node node1) {
while (node1.left != null) {
node1 = node1.left;
}
return node1;
}
private int compare(T data, T data1) {
return data.compareTo(data1);
}
public void printBST(T data) {
printTree(root, data);
}
private void printTree(Node node, T data) {
if (node == null) {
return;
}
System.out.println(data + " + " + node.data);
printTree(node.left, data);
printTree(node.right, data);
}
public int getHeight() {
return height(root);
}
private int height(Node node) {
if (node == null) {
return 0;
} else {
return 1 + Math.max(height(node.left), height(node.right));
}
}
public void print() {
println(root);
}
private void println(Node node) {
LinkedList<T> q = new LinkedList<T>();
q.add((T) node.data);
if (node == null) {
return;
}
int size = getSize();
while (size > 0) {
System.out.print(q);
q.clear();
if (node.left != null) {
q.add((T) node.left.data);
size--;
}
if (node.right != null) {
q.add((T) node.right.data);
size--;
}
if (node.right != null && node.left != null) {
System.out.println();
}
if (size > 1) {
System.out.println(",");
}
}
}
public boolean sameTree(Node root1, Node root2) {
if (root1 == null && root2 == null) {
return true;
}
if (root1 != null && root2 != null) {
return root1.data == root2.data && sameTree(root1.left, root2.left) && sameTree(root1.right, root2.right);
} else {
return false;
}
}
}
I hope this helps to you
I just need a little direction to solve this Data Structure problem. I have to create an add() method for a BST. I know how to do the recursive solution to this problem but what is a non-recursive solution to this? Here is my Class.
import java.util.*;
public class BST
{
// instance variables
private BSTNode m_root;
private int m_size;
// constructor
public BST()
{
m_root = null;
m_size = 0;
}
// add a value into the tree
public void add(int v)
{ BSTNode current = m_root;
if(current == null) {
m_root=new BSTNode(v);
m_size++;
}
else
{
while(current!=null) {
if(current.getInfo() > v) {
if(current.getLeft() == null) {
m_root.setLeft(new BSTNode(v));
m_size++;
current=null;
}
else
current = current.getLeft();
}
else if(current.getInfo()< v) {
if(current.getRight() == null) {
m_root.setRight(new BSTNode(v));
current=null;
m_size++;
}
else current = current.getRight();
}}}}
// get the size of the tree
public int size()
{
return m_size;
}
// empty the tree
public void clear()
{
m_root = null;
m_size = 0;
}
}
Figured it out!
public void add(int v)
{ BSTNode current = m_root;
if(current == null) {
m_root=new BSTNode(v);
m_size++;
}
else
{
while(current!=null) {
if(current.getInfo()==v)
{current=null;}
else if(current.getInfo() > v) {
if(current.getLeft() == null) {
m_root.setLeft(new BSTNode(v));
m_size++;
current=null;
}
else
current = current.getLeft();
}
else if(current.getInfo()< v) {
if(current.getRight() == null) {
m_root.setRight(new BSTNode(v));
current=null;
m_size++;
}
else current = current.getRight();
}}
}
}
BSTNode current = m_root;
if(current == null) {
current = new BSTNode(v);
return;
}
while(true) {
if(current.key > v) {
if(current.left == null) {
current.left = new BSTNode(v);
break;
}
else
current = current.left;
}
else if(current.key < v) {
if(current.right == null) {
current.right = new BSTNode(v);
breakl;
}
else current = current.right;
}
}
I have fixed the issue with the infinite loops but it seems like now when I try to use the function find, it always returns a value null. Any ideas of what's happening? Also for some reason I'm getting a NullPointerException in my delete function. Please can you help me here guys?
package ui;
import java.time.LocalDate;
import bp.BinaryTree;
public class Main {
public static void main(String[] args) {
BinaryTree myTree = new BinaryTree();
myTree.insert(LocalDate.of(2014,12,01));
myTree.insert(LocalDate.of(2014,12,02));
myTree.insert(LocalDate.of(2014,12,03));
myTree.insert(LocalDate.of(2013,12,04));
myTree.insert(LocalDate.of(2012,12,04));
myTree.insert(LocalDate.of(2011,12,04));
myTree.insert(LocalDate.of(2010,12,04));
myTree.insert(LocalDate.of(2014,12,04));
myTree.insert(LocalDate.of(2014,12,05));
myTree.insert(LocalDate.of(2014,12,06));
myTree.insert(LocalDate.of(2014,12,07));
System.out.println(myTree);
System.out.println(myTree.getSize());
System.out.println(myTree.showMaximumValue());
System.out.println(myTree.showMinimumValue());
System.out.println(myTree.find(LocalDate.of(2014,12,07)));
}
public class BinaryTree implements IBinaryTree {
public Node root = null;
private int sizeOfTree = 0;
#Override
public LocalDate showMinimumValue() {
Node current;
Node last=null;
current = root;
while (current != null) {
last = current;
current = current.getLeftChild();
}
return last.getDate();
}
#Override
public LocalDate showMaximumValue() {
Node current;
Node last=null;
current = root;
while (current != null) {
last = current;
current = current.getRightChild();
}
return last.getDate();
}
#Override
public boolean isEmpty() {
if (root == null) {
return true;
} else
return false;
}
public int getDepth(Node n) {
int currentDepth = 0;
int depth = 0;
if (n != null) {
currentDepth++;
if (currentDepth > depth) {
depth = currentDepth;
}
getDepth(n.getLeftChild());
getDepth(n.getRightChild());
currentDepth--;
}
return depth;
}
#Override
public int getSize() {
return sizeOfTree;
}
#Override
public void clear() {
root = null;
}
#Override
public void insert(LocalDate valueToInsert) {
if (isEmpty()) {
root = new Node(valueToInsert);
sizeOfTree++;
} else {
Node n = root;
Node oldParent = null;
boolean lastDirectWasLeft = false;
sizeOfTree++;
while (n != null) {
oldParent = n;
if (valueToInsert.isBefore(n.getDate())) {
n = n.getLeftChild();
lastDirectWasLeft = true;
} else {
n = n.getRightChild();
lastDirectWasLeft = false;
}
}
if (lastDirectWasLeft) {
oldParent.setLeftChild(new Node(valueToInsert));
} else {
oldParent.setRightChild(new Node(valueToInsert));
}
}
}
#Override
public void delete(LocalDate valueToDelete) {
Node current = root;
Node parent = root;
boolean isLeftChild = true;
while (current.getDate() != valueToDelete) {
parent = current;
if (valueToDelete.isBefore(current.getDate())) {
isLeftChild = true;
current = current.getLeftChild();
} else {
isLeftChild= false;
current = current.getRightChild();
}
if (current == null) {
break;
}
}
//When there is no children, cut the string
if(current.getLeftChild().equals(null)
&& current.getRightChild().equals(null)) {
if (current == root) {
root = null;
} else if (isLeftChild) {
parent.setLeftChild(null);
} else {
parent.setRightChild(null);
}
}
//When there is no right child, replace with left child
else if (current.getRightChild().equals(null)) {
if (current == root) {
root = current.getLeftChild();
} else if (isLeftChild) {
parent.setLeftChild(current.getLeftChild());
} else
parent.setRightChild(current.getLeftChild());
}
//When there is no left child, replace with right child
else if (current.getLeftChild() == null) {
if (current == root) {
root = current.getRightChild();
} else if (isLeftChild) {
parent.setLeftChild(current.getRightChild());
} else
parent.setRightChild(current.getRightChild());
}
//has grandchildren, pass them to the grandpas
else {
//find the grandchildren
Node successor = getSuccessor(current);
if (current == root) {
root = successor;
} else if (isLeftChild) {
parent.setLeftChild(successor);
} else {
parent.setRightChild(successor);
}
//bring grandkids and granppas together
successor.setLeftChild(current.getLeftChild());
}
}
private Node getSuccessor (Node otroNode) {
Node successorParent = otroNode;
Node successor = otroNode;
Node current = otroNode.getRightChild();
while (current != null) {
successorParent = successor;
successor = current;
current = current.getLeftChild();
}
if (successor != otroNode.getRightChild()) {
successorParent.setLeftChild(successor.getRightChild());
successor.setRightChild(otroNode.getRightChild());
}
return successor;
}
#Override
public Node find(LocalDate valueToFind) {
Node current = root;
while (current.getDate() != valueToFind) {
if (valueToFind.isBefore(current.getDate())) {
current = current.getLeftChild();
} else {
current = current.getRightChild();
}
if (current == null) {
return null;
}
}
return current;
}
if (isEmpty()) {
return null;
}
if (root.getDate().isAfter(valueToFind)) {
find(root.getLeftChild().getDate());
} else if (root.getDate().isBefore(valueToFind)) {
find(root.getRightChild().getDate());
} else if (root.getDate().equals(valueToFind) ) {
return root;
}
return null;
**/
private String toString(Node todoElArbol) {
if (todoElArbol == null){
return "";
} else {
return (toString(todoElArbol.getLeftChild()) + ","
+ todoElArbol.getDate() + ","
+ toString(todoElArbol.getRightChild()))
.replaceAll(",+", ",").replaceAll("^,", "").replaceAll(",$", "");
}
}
#Override
public String toString() {
return toString(root);
}
}
The Node class:
import java.time.LocalDate;
public class Node implements IBinaryTreeNode {
private LocalDate date;
private Node leftChild;
private Node rightChild;
public Node (LocalDate valueToInsert) {
date = valueToInsert;
}
#Override
public LocalDate getDate() {
return date;
}
#Override
public void setDate(LocalDate pDate) {
date = pDate;
}
#Override
public Node getLeftChild() {
return leftChild;
}
#Override
public void setLeftChild(Node pLeftChild) {
leftChild = pLeftChild;
}
#Override
public Node getRightChild() {
return rightChild;
}
#Override
public void setRightChild(Node pRightChild) {
rightChild = pRightChild;
}
}
Your binary search is.... broken.
#Override
public Node find(LocalDate valueToFind) {
if (isEmpty()) {
return null;
}
if (root.getDate().isAfter(valueToFind)) {
find(root.getLeftChild().getDate());
} else if (root.getDate().isBefore(valueToFind)) {
find(root.getRightChild().getDate());
} else if (root.getDate() == valueToFind) {
return root;
}
return null;
}
That method is supposed to recursively find a value in the tree (a depth-first search).
Methods like that are normally implemented in two parts, the public part, and the implementation for the recursion:
#Override
public Node find(LocalDate valueToFind) {
if (isEmpty()) {
return null;
}
return findRecursive(root, valueToFind);
}
then the private/recursive method:
private Node findRecursive(Node node, LocalDate valueToFind) {
if (node == null) {
return null;
}
if (node.getDate().isAfter(valueToFind)) {
return findRecursive(node.getLeftChild(), valueToFind);
}
if (node.getDate().isBefore(valueToFind)) {
return findRecursive(root.getRightChild(), valueToFind);
}
if (node.getDate().equals(valueToFind)) {
return node;
}
return null;
}
Note, no references to root in the recursive call, and also changed the == comparison to .equals(...).
I suggest the class Node should implement the Comparable interface, then you can get rid of the help method isBefore and isAfter, which will make your code much more readable.