How do I make a BST when I have an array list of 100 elements like {3,2,6,7,...,99}?
I believe TreeSet is an implementation of a binary search tree. Since integers have a natural ordering you could simply loop through your array of integers and add them all to a TreeSet<Integer>.
Note also, that there is a method Arrays.binarySearch that does a binary search in a sorted array.
int[] someInts = {3,2,6,7, /*...,*/ 99};
// use a TreeSet
TreeSet<Integer> ints = new TreeSet<Integer>();
for (int i : someInts)
ints.add(i);
System.out.println(ints.contains(2)); // true
System.out.println(ints.contains(5)); // false
// or sort the array and use Arrays.binarySearch
Arrays.sort(someInts);
System.out.println(Arrays.binarySearch(someInts, 2) >= 0); // true
System.out.println(Arrays.binarySearch(someInts, 5) >= 0); // false
Unless you want to implement everything yourself (in that case, you might want to check here) you should take a look at [Collections.binarySearch][2].
[2]: http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html#binarySearch(java.util.List, java.lang.Object)
1st sort this array , than use BST
EDIT
1- BST works on the sorted array.
2- Use this psudo code See Here
I recently finished a project where we basically had to do this.
You could take a look at this class
Edit: This is in C++, I see you're coding in Java, my apologies!
/**************************************
* Tree.cpp - Created by DT
**************************************
*
* Functions:
*
* public:
* Tree();
* void addNode(int);
* bool findID(int);
* Node* findNode(int);
* Node* findParent(int);
* bool deleteID(int);
* Node* findMaximum(Node*);
* Node* findMinimum(Node*);
* void printInOrder();
* void printPreOrder();
* void printPostOrder();
* int recurseHeight(Node*);
* int getHeight();
* void inOrder(Node*);
* void preOrder(Node*);
* void postOrder(Node*);
*
***************************************/
#include <iostream>
#include "Node.h"
#include "Tree.h"
using namespace std;
Tree::Tree() {
root = NULL;
}
///////////////////////////////
// AddNode Function:
///////////////////////////////
void Tree::addNode(int id) {
if(findNode(id)) {
cout << "This ID already exists in the tree" << endl;
return;
}
//if(id == 2147483647) {
// cout << "Overflow Detected: Did you enter a really big number?\n";
// cout << "This ID is being stored as 2147483647\n";
//}
Node *newNode = new Node();
newNode->id = id;
if(root == NULL) {
root = newNode;
return;
}
Node *nextNode = root;
Node *lastNode = nextNode;
while(nextNode != NULL) {
if(id <= nextNode->id) {
lastNode = nextNode;
nextNode = nextNode->leftChild;
}
else {
lastNode = nextNode;
nextNode = nextNode->rightChild;
}
}
if(id <= lastNode->id)
lastNode->leftChild = newNode;
else
lastNode->rightChild = newNode;
}
///////////////////////////////
// FindID Function:
///////////////////////////////
bool Tree::findID(int id) {
Node *finder = root;
while(finder != NULL) {
if(id == finder->id)
return true;
if(id <= finder->id)
finder = finder->leftChild;
else
finder = finder->rightChild;
}
return false;
}
///////////////////////////////
// FindNode Helper Function:
///////////////////////////////
Node* Tree::findNode(int id) {
Node *finder = root;
while(finder != NULL) {
if(id == finder->id)
return finder;
if(id <= finder->id)
finder = finder->leftChild;
else
finder = finder->rightChild;
}
return NULL;
}
///////////////////////////////
// FindParent Helper Function:
///////////////////////////////
Node* Tree::findParent(int id) {
Node *parent = NULL;
Node *finder = root;
while(finder != NULL) {
if(id == finder->id)
return parent;
parent = finder;
if(id <= finder->id)
finder = finder->leftChild;
else
finder = finder->rightChild;
}
return NULL;
}
///////////////////////////////
// DeleteID Function:
///////////////////////////////
bool Tree::deleteID(int id) {
if(root == NULL)
return false;
Node *toDelete = findNode(id); //Find the node to delete
if(toDelete == NULL) //If we can't find it, return false
return false;
Node *parent = findParent(id); //Find the parent of the node to delete
Node *justInCase; //In case we are deleting the root node
bool deletingRoot = false; //This is a special case so handle it differently
if(root->id == id) { //If we're deleting the root node
justInCase = new Node(); //Let's create a fake parent for the root
justInCase->leftChild = root; //Just to make sure that we can run checks on parents
justInCase->rightChild = NULL;
justInCase->id = 0; //Later on in the code
parent = justInCase; //Set the parent of the root to our new fake node
deletingRoot = true; //Let the end of our function know we're deleting the root
}
bool deletingLeftChild = (parent->leftChild == toDelete);
if(toDelete->leftChild == NULL && toDelete->rightChild == NULL) {
if(toDelete == root)
root = NULL;
if(deletingLeftChild)
parent->leftChild = NULL;
else
parent->rightChild = NULL;
delete toDelete;
return true;
}
if((toDelete->leftChild == NULL || toDelete->rightChild == NULL) && (parent != NULL && !deletingRoot)) {
if(deletingLeftChild)
parent->leftChild = (toDelete->leftChild == NULL) ? toDelete->rightChild : toDelete->leftChild;
else
parent->rightChild = (toDelete->leftChild == NULL) ? toDelete->rightChild : toDelete->leftChild;
delete toDelete;
return true;
}
Node *replacer = findMaximum(toDelete->leftChild); //Replace the node we're deleting with the hightest LEFT Child
if(replacer == NULL || replacer == toDelete) //If we can't find a left child (in case of deleting root)
replacer = findMinimum(toDelete->rightChild); //Find the smallest RIGHT child
Node *replacerParent = findParent(replacer->id); //Find the parent of this child
if(replacerParent != NULL) { //If this child has a parent
if(replacerParent->leftChild == replacer) { //If the child is to the left of the parent
if(replacer->leftChild != NULL) //And the left child has a child of its own (in case of findMinimum/maximum)
replacerParent->leftChild = replacer->leftChild;//set the parent's child to this child's node
else
replacerParent->leftChild = NULL; //Otherwise, set the parent's child to NULL
}
else { //In the case of Right Child
if(replacer->rightChild != NULL) //Do the same thing
replacerParent->rightChild = replacer->rightChild;
else
replacerParent->rightChild = NULL;
}
}
toDelete->id = replacer->id; //Swap the IDs of the nodes we're deleting
delete replacer; //And delete the minimum or maximum that we found
return true;
}
///////////////////////////////
// FindMaximum Helper Function:
///////////////////////////////
Node* Tree::findMaximum(Node *theNode) {
if(theNode == NULL)
return NULL;
Node *finder = theNode;
Node *last = finder;
while(finder != NULL) {
last = finder;
finder = finder->rightChild;
}
return last;
}
///////////////////////////////
// FindMinimum Helper Function:
///////////////////////////////
Node* Tree::findMinimum(Node *theNode) {
if(theNode == NULL)
return NULL;
Node *finder = theNode;
Node *last = finder;
while(finder != NULL) {
last = finder;
finder = finder->leftChild;
}
return last;
}
///////////////////////////////
// PrintInOrder Function:
///////////////////////////////
void Tree::printInOrder() {
inOrder(root); //Recurse through our root
cout << "\b " << endl;
}
///////////////////////////////
// PrintPostOrder Function:
///////////////////////////////
void Tree::printPostOrder() {
postOrder(root); //Recurse through our root
cout << "\b " << endl;
}
///////////////////////////////
// PrintPreOrder Function:
///////////////////////////////
void Tree::printPreOrder() {
preOrder(root); //Recurse through our root
cout << "\b " << endl;
}
///////////////////////////////
// RecurseHeight Function:
///////////////////////////////
int Tree::recurseHeight(Node *node) {
if(node == NULL) return -1;
return 1 + max(recurseHeight(node->leftChild),recurseHeight(node->rightChild));
}
///////////////////////////////
// GetHeight Function:
///////////////////////////////
int Tree::getHeight() { return recurseHeight(root); } //Recurse through our root
///////////////////////////////
// InOrder Function:
///////////////////////////////
void Tree::inOrder(Node *cNode) {
if(cNode == NULL)
return;
inOrder(cNode->leftChild);
cout << cNode->id << "-";
inOrder(cNode->rightChild);
}
///////////////////////////////
// PostOrder Function:
///////////////////////////////
void Tree::postOrder(Node *cNode) {
if(cNode == NULL)
return;
postOrder(cNode->leftChild);
postOrder(cNode->rightChild);
cout << cNode->id << "-";
}
///////////////////////////////
// PreOrder Function:
///////////////////////////////
void Tree::preOrder(Node *cNode) {
if(cNode == NULL)
return;
cout << cNode->id << "-";
preOrder(cNode->leftChild);
preOrder(cNode->rightChild);
}
The node class:
/**************************************
* Node.cpp - Created by DT
**************************************
*
* An incredibly simple class that
* apparently deserves its own header
*
***************************************/
#include "Node.h"
#include <iostream>
Node::Node() {
leftChild = NULL;
rightChild = NULL;
id = NULL;
}
Related
I am trying to return the data held by the nth item of a BST, I'm trying to do an inorder traversal with a counter, and when the counter is larger than n, return the current node. My current code seems to always return the first item, and I can't see where my logic is wrong. I only wrote the nth and inOrder methods, the rest were provided. I think I'm incrementing my counter too often, is that the cause or am I doing something else wrong. I'll post the main method I'm testing with below as well.
import java.util.NoSuchElementException;
public class BST {
private BTNode<Integer> root;
public BST() {
root = null;
}
public boolean insert(Integer i) {
BTNode<Integer> parent = root, child = root;
boolean goneLeft = false;
while (child != null && i.compareTo(child.data) != 0) {
parent = child;
if (i.compareTo(child.data) < 0) {
child = child.left;
goneLeft = true;
} else {
child = child.right;
goneLeft = false;
}
}
if (child != null)
return false; // number already present
else {
BTNode<Integer> leaf = new BTNode<Integer>(i);
if (parent == null) // tree was empty
root = leaf;
else if (goneLeft)
parent.left = leaf;
else
parent.right = leaf;
return true;
}
}
public int greater(int n) {
if (root == null) {
return 0;
}
else {
return n;
}
}
int c = 0;
public int nth(int n) throws NoSuchElementException {
BTNode<Integer> node = null;
if (root == null) {
throw new NoSuchElementException("Element " + n + " not found in tree");
}
else {
if (root != null){
node = inOrder(root, n);
}
}
return node.data;
}
public BTNode inOrder(BTNode<Integer> node, int n) {
c++;
while (c <= n) {
if (node.left != null) {
inOrder(node.left, n);
}
c++;
if (node.right != null) {
inOrder(node.right, n);
}
}
return node;
}
}
class BTNode<T> {
T data;
BTNode<T> left, right;
BTNode(T o) {
data = o;
left = right = null;
}
}
public class bstTest {
public static void main(String[] args) {
BST tree = new BST();
tree.insert(2);
tree.insert(5);
tree.insert(7);
tree.insert(4);
System.out.println(tree.nth(2));
}
}
An invariant you should consider is that when n = sizeOfLeftSubtree + 1, then return that node. If n is less, then go left. If n is greater, then go right and reduce n by sizeOfLeftSubtree+1. Note that I map n=1 to the first element (the leftmost element).
You could trivially calculate the size of a subtree recursively, or you can store the size at every root (every node is a root of a subtree) modifying you insert method (save in a stack/queue all nodes visited and if a new node is added just increment all sizes by 1).
If the size is stored the complexity will be O(log n). If not if could become O(n^2).
public int nth(int n) throws NoSuchElementException {
if( sizeOfTree(this.root) < n || n < 1)
throw new NoSuchElementException("Element " + n + " not found in tree");
BTNode<Integer> root = this.root;
boolean found = false;
do{
int sizeOfLeftSubtree = sizeOfTree(root.left);
if( sizeOfLeftSubtree + 1 == n ){
found = true;
}else if( n < sizeOfLeftSubtree+1 ){
root = root.left;
}else if( sizeOfLeftSubtree+1 < n ){
root = root.right;
n -= sizeOfLeftSubtree+1;
}
}while( !found );
return root.data;
}
public int sizeOfTree(BTNode<Integer> root){
if( root == null )
return 0;
else
return sizeOfTree(root.left) + 1 + sizeOfTree(root.right);
}
You don't change node in the inOrder method.
public BTNode inOrder(BTNode<Integer> node, int n) {
c++;
while (c <= n) {
if (node.left != null) {
// **** Add this - or something.
node = inOrder(node.left, n);
}
c++;
if (node.right != null) {
// **** Add this - or something.
node = inOrder(node.right, n);
}
}
return node;
}
Not suggesting this is the bug you are trying to fix but it is certainly a problem with the code.
My code below will remove a tree with two children, or one child. But a leaf (a tree with zero children) I can't seem to crack. My BSTNode<E> also contains a .parent which identifies it's parent. I'm not sure if that would help with this implementation or not.
#Override
public E delete(E target) {
return delete(this.root, target);
}
private E delete(BSTNode<E> localRoot, E target) {
// ... Trying to delete an item that's not in the tree?
if (localRoot == null) {
return null;
}
int compareResult = c.compare(target, localRoot.data);
// Traverse the tree...
if (compareResult < 0) {
return delete(localRoot.left, target);
} else if (compareResult > 0) {
return delete(localRoot.right, target);
} else {
// Found the item! Oh boy here we go!
E retVal = localRoot.data;
/*
* Both left and right exist under the targeted node.
* Find the largest child under the right side of the node.
* Set the largest data to the 'deleted' node, then delete that node.
*/
if (localRoot.left != null && localRoot.right != null) {
/*
* Two children, find the smallest and assign it.
*/
localRoot.data = localRoot.right.data;
localRoot.right = findLargestChild(localRoot.right);
} else if (localRoot.left != null) {
localRoot.data = localRoot.left.data;
localRoot.left = findSmallestChild(localRoot.left);
} else if (localRoot.right != null) {
localRoot.data = localRoot.right.data;
localRoot.right = findLargestChild(localRoot.right);
} else {
/*
* TODO:
* Remove a leaf.
*/
System.out.println("Removing leaf..." + localRoot.data.toString());
localRoot = null;
}
return retVal;
}
}
Using localRoot.parent I was able to delete (null) the child of the localRoot's parent. This feels backwards, but it's passing JUnit Tests...
private E delete(BSTNode<E> localRoot, E target) {
// ... Trying to delete an item that's not in the tree?
if (localRoot == null) {
return null;
}
int compareResult = c.compare(target, localRoot.data);
// Traverse the tree...
if (compareResult < 0) {
return delete(localRoot.left, target);
} else if (compareResult > 0) {
return delete(localRoot.right, target);
} else {
// Found the item! Oh boy here we go!
E retVal = localRoot.data;
if (localRoot.right != null) {
/*
* Assign the largest value to the tree.
*/
localRoot.data = localRoot.right.data;
localRoot.right = findLargestChild(localRoot.right);
} else if (localRoot.left != null) {
/*
* Since the largest value didn't exist, assign the smallest.
*/
localRoot.data = localRoot.left.data;
localRoot.left = findSmallestChild(localRoot.left);
} else {
/*
* Remove a leaf.
*/
System.out.println("Removing leaf or left..." + localRoot.data.toString());
if (c.compare(target, localRoot.parent.left.data) == 0) {
localRoot.parent.left = null;
} else {
localRoot.parent.right = null;
}
}
return retVal;
}
}
I was doing an assignment in which I'm supposed to create a binary tree and define given functions from its abstract superclass (AbstractBinaryTree.java).
While working on a function called getNumbers() which is basically going to traverse through the whole tree whilst adding values from each node to an array list which it returns. There seems to be a null pointer in one of my if statements.
AbstractBinaryTree.java
import java.util.ArrayList;
public abstract class AbstractBinaryTree
{
protected Node root;
protected int sizeOfTree;
public AbstractBinaryTree()
{
root = null;
sizeOfTree = 0;
}
public int size(){ return sizeOfTree; }
/** compute the depth of a node */
public abstract int depth(Node node);
/** Check if a number is in the tree or not */
public abstract boolean find(Integer i);
/** Create a list of all the numbers in the tree. */
/* If a number appears N times in the tree then this */
/* number should appear N times in the returned list */
public abstract ArrayList<Integer> getNumbers();
/** Adds a leaf to the tree with number specifed by input. */
public abstract void addLeaf(Integer i);
/** Removes "some" leaf from the tree. */
/* If the tree is empty should return null */
public abstract Node removeLeaf();
// these methods are only needed if you wish
// use the TreeGUI visualization program
public int getheight(Node n){
if( n == null) return 0;
return 1 + Math.max(
getheight(n.getLeft()) , getheight(n.getRight())
);
}
public int height(){ return getheight(root); }
}
Node.java File.
public class Node{
protected Integer data;
protected Node left;
protected Node right;
public Node(Integer data)
{
this.data = data;
this.left = this.right = null;
}
public Node(Integer data, Node left, Node right){
this.data = data;
this.left = left;
this.right = right;
}
public Integer getData(){ return this.data; }
public Node getLeft(){ return this.left; }
public Node getRight(){ return this.right; }
public void setLeft(Node left){ this.left = left; }
public void setRight(Node right){ this.right = right; }
public void setData(Integer data){ this.data = data; }
}
BinaryTree.java
import java.util.ArrayList;
import java.util.*;
// Student Name: Adrian Robertson
// Student Number: 101020295
//
// References: Collier, R. "Lectures Notes for COMP1406C- Introduction to Computer Science II" [PDF documents]. Retrieved from cuLearn: https://www.carleton.ca/culearn/(Winter2016).//
// References: http://codereview.stackexchange.com/questions/13255/deleting-a-node-from-a-binary-search-tree
// http://www.algolist.net/Data_structures/Binary_search_tree/Removal
// http://www.geeksforgeeks.org/inorder-tree-traversal- without-recursion-and-without-stack/
public class BinaryTree extends AbstractBinaryTree
{
protected Node root = new Node(12);
public static BinaryTree create()
{
BinaryTree tempTree = new BinaryTree();
//creating all the nodes
Node temp10 = new Node(10);
Node temp40 = new Node(40);
Node temp30 = new Node(30);
Node temp29 = new Node(29);
Node temp51 = new Node(51);
Node temp61 = new Node(61);
Node temp72 = new Node(72);
Node temp31 = new Node(31);
Node temp32 = new Node(32);
Node temp42 = new Node(42);
Node temp34 = new Node(34);
Node temp2 = new Node(2);
Node temp61x2 = new Node(61);
Node temp66 = new Node(66);
Node temp3 = new Node(3);
Node temp73 = new Node(73);
Node temp74 = new Node(74);
Node temp5 = new Node(5);
//setting up the tree
if (tempTree.root.getData() == null)
{
tempTree.root.setData(12);
tempTree.root.setLeft(temp10);
tempTree.root.setRight(temp40);
}
temp10.setLeft(temp30);
temp30.setRight(temp29);
temp29.setRight(temp51);
temp51.setLeft(temp61);
temp51.setRight(temp72);
temp40.setLeft(temp31);
temp31.setLeft(temp42);
temp31.setRight(temp34);
temp34.setLeft(temp61x2);
temp61x2.setLeft(temp66);
temp61x2.setRight(temp73);
temp40.setRight(temp32);
temp32.setRight(temp2);
temp2.setLeft(temp3);
temp3.setRight(temp74);
temp74.setLeft(temp5);
return tempTree;
}
public int depth(Node node)
{
Node current = this.root;
int counter = 1;
while(node != current)
{
if (node.getData() > current.getData())
current = current.getRight();
if (node.getData() < current.getData())
current = current.getLeft();
}
return counter;
}
public boolean find(Integer i)
{
boolean found = false;
Node current = this.root;
if (i == current.getData())
found = true;
while (i != current.getData())
{
if (i > current.getData())
current = current.getRight();
if (i < current.getData())
current = current.getLeft();
if (i == current.getData())
found = true;
}
return found;
}
public ArrayList<Integer> getNumbers()
{
ArrayList<Integer> temp = new ArrayList<Integer>();
Node current = this.root;
Node Pre = new Node(null);
while (current.getData() != null )
{
if (current.getLeft().getData() == null)
{
temp.add(current.getData());
current = current.getRight();
}
else
{
/* Find the inorder predecessor of current */
Pre = current.getLeft();
while(Pre.getRight() != null && Pre.getRight() != current)
Pre = Pre.getRight();
/* Make current as right child of its inorder predecessor */
if (Pre.getRight() == null)
{
Pre.setRight(current);
current = current.getLeft();
}
/* Revert the changes made in if part to restore the original tree i.e., fix the right child of predecssor */
else
{
Pre.setRight(null);
temp.add(current.getData());
current = current.getRight();
}/* End of if condition Pre.right == NULL */
}/* End of if condition current.left == NULL*/
}/*End of while */
Collections.sort(temp);
return temp;
}
public void addLeaf(Integer i)
{
insert(this.root, i);
}
public static void insert(Node node, int value) //insert a node Based on provided argument where node is the root of tree
{
if (node == null)
{
Node first = new Node(value);
node = first;
}
else if (value < node.getData())
{
if (node.left != null)
{
insert(node.left, value);
}
else
{
System.out.println(" > Inserted " + value + " to left of node " + node.getData());
Node newNode = new Node(value);
node.left = newNode;
}
}
else if (value > node.getData())
{
if (node.right != null)
{
insert(node.right, value);
}
else
{
System.out.println(" > Inserted " + value + " to right of node " + node.getData());
Node newNode = new Node(value);
node.right = newNode;
}
}
}
public Node removeLeaf()
{
Node tempA = new Node(61); //create a new node with that value
deleteNodeBST(this.root, 61); //delete the node containing that leaf value
return tempA; //return the copy of that node
}
//delete given node with given value
public boolean deleteNodeBST(Node node, int data) {
ArrayList<Integer> temp = this.getNumbers();
if (node == null) {
return false;
}
if (node.getData() == data) {
if ((node.getLeft() == null) && (node.getRight() == null)) {
// leaf node
node = null;
return true;
}
if ((node.getLeft() != null) && (node.getRight() != null)) {
// node with two children
node.setData(temp.get(0));
return true;
}
// either left child or right child
if (node.getLeft() != null) {
this.root.setLeft(node.getLeft());
node = null;
return true;
}
if (node.getRight() != null) {
this.root.setRight(node.getRight());
node = null;
return true;
}
}
this.root = node;
if (node.getData() > data) {
return deleteNodeBST(node.getLeft(), data);
} else {
return deleteNodeBST(node.getRight(), data);
}
}
public static void main(String args[])
{
BinaryTree myTree = new BinaryTree();
myTree.create();
System.out.println(myTree.getNumbers());
}
}
The create function creates a binary tree and returns that binary tree. This is the predefined binary tree that I was supposed to create according to assignment guidelines. I understand that the tree values are not organised properly as they would be in a proper binary tree. Is that was causes the null pointer during traversal? Cause the traversal is taylored to work for a proper Binary tree.
In class BinaryTree, you initialize the left and right of your root node only if the haven't data. But the root node is create with data...
You should invert the condition in :
//setting up the tree
if (tempTree.root.getData() == null)
And add a test in getNumbers() :
if (current.getLeft() == null || current.getLeft().getData() == null)
In the BinaryTree class, getNumbers() method and while loop. Maybe your problem is here:
if (current.getLeft().getData() == null) {
temp.add(current.getData());
current = current.getRight();
}
When you call current.getLeft(), it will return null when the left Node is null. And then, you call getData() it will throw a NullPointerException. If you're not sure that it always not null check it before you call any methods of it. Example you can change the if statement to:
if (current.getLeft() != null && current.getLeft().getData() == null) {
temp.add(current.getData());
current = current.getRight();
}
Or:
Node left = current.getLeft();
if (left == null) {
//TODO something here
} else if (left.getData() == null) {
temp.add(current.getData());
current = current.getRight();
}
Please update your getNumbers - method accordingly,
You need to put right checks before work with reference type.
public ArrayList<Integer> getNumbers()
{
ArrayList<Integer> temp = new ArrayList<Integer>();
Node current = this.root;
Node Pre = new Node(null);
while (current != null && current.getData() != null ) // Fix here... Add : current != null
{
if (current.getLeft() != null && current.getLeft().getData() == null) // Fix here... Add : current.getLeft() != null
{
temp.add(current.getData());
current = current.getRight();
}
else
{
/* Find the inorder predecessor of current */
Pre = current.getLeft();
while(Pre != null && Pre.getRight() != null && Pre.getRight() != current) // Fix here... Add : Pre != null
Pre = Pre.getRight();
/* Make current as right child of its inorder predecessor */
if (Pre != null && Pre.getRight() == null) // Fix here... Add : Pre != null
{
Pre.setRight(current);
current = current.getLeft();
}
/* Revert the changes made in if part to restore the original tree i.e., fix the right child of predecssor */
else
{
if(Pre != null){ // Fix here... Add : Pre != null
Pre.setRight(null);
}
temp.add(current.getData());
current = current.getRight();
}/* End of if condition Pre.right == NULL */
}/* End of if condition current.left == NULL*/
}/*End of while */
Collections.sort(temp);
return temp;
}
This a program creates balanced binary search tree from an array integer and later on, prints the value in-order ( X.left, X, X.right). Any suggestion for improving the program appreciated.
It would be good to note, there are several other ways for traversing a BST. Such as -
Pre-order : X, X.left, X.right
Post-order : X.left, X.right, X
Note # I eventually solved the issue with some help from the user of this program. It needed to change some conditions inside the createMinimalBST method.
// we need to stop recursion there as one element exist
if (start == mid-1) {
}
// we need to stop recursion there as one element exist
if (end == mid+1) {
}
THANK YOU.
// import java.util.Arrays;
// import java.util.LinkedList;
import java.util.*;
class Node {
int key;
Node leftChild;
Node rightChild;
Node(int key) {
this.key = key;
}
Node() {
// null constructor
}
public String toString() {
return "\n"+key+" ";
}
}
public class BinaryTree {
Node root;
static int TWO_NODES_FOUND = 2;
static int ONE_NODE_FOUND = 1;
static int NO_NODES_FOUND = 0;
BinaryTree (){
root = null;
}
public void addNode(int key) {
Node newNode = new Node(key);
// If there is no root this becomes root
if (root == null) {
root = newNode;
}
else {
// Set root as the Node we will start
// with as we traverse the tree
Node focusNode = root;
Node parent;
while (true) {
parent = focusNode;
if (key < focusNode.key) {
focusNode = focusNode.leftChild;
if (focusNode == null) {
parent.leftChild = newNode;
return; // All Done
}
} // end of if
else {
focusNode = focusNode.rightChild;
if (focusNode == null) {
parent.rightChild = newNode;
return;
}
}
}
}
}
// get the height of binary tree
public int height(Node root) {
if (root == null)
return -1;
Node focusNode = root;
int leftHeight = focusNode.leftChild != null ? height( focusNode.leftChild) : 0;
int rightHeight = focusNode.rightChild != null ? height( focusNode.rightChild) : 0;
return 1 + Math.max(leftHeight, rightHeight);
}
// METHODS FOR THE TREE TRAVERSAL
// inOrderTraverseTree : i) X.left ii) X iii) X.right
public void inOrderTraverseTree(Node focusNode) {
if (focusNode != null) {
inOrderTraverseTree(focusNode.leftChild);
// System.out.println(focusNode);
System.out.print( focusNode );
inOrderTraverseTree(focusNode.rightChild);
}
// System.out.println();
}
// preOrderTraverseTree : i) X ii) X.left iii) X.right
public void preorderTraverseTree(Node focusNode) {
if (focusNode != null) {
System.out.println(focusNode);
preorderTraverseTree(focusNode.leftChild);
preorderTraverseTree(focusNode.rightChild);
}
}
// postOrderTraverseTree : i) X.left ii) X.right iii) X
public void postOrderTraverseTree(Node focusNode) {
if (focusNode != null) {
preorderTraverseTree(focusNode.leftChild);
preorderTraverseTree(focusNode.rightChild);
System.out.println(focusNode);
}
}
// get certain node from it's key
public Node findNode(int key) {
Node focusNode = root;
while (focusNode.key != key) {
if (key < focusNode.key) {
focusNode = focusNode.leftChild;
} else {
focusNode = focusNode.rightChild;
}
if (focusNode == null)
return null;
}
return focusNode;
}
public boolean remove(int key) {
Node focusNode = root;
Node parent = root;
boolean isItALeftChild = true;
// we will remove the focusNode
while (focusNode.key != key) {
parent = focusNode;
if (key < focusNode.key) {
isItALeftChild = true;
focusNode = focusNode.leftChild;
}
else {
isItALeftChild = false;
focusNode = focusNode.rightChild;
}
if (focusNode == null)
return false;
}
// no child
if (focusNode.leftChild == null && focusNode.rightChild == null) {
if (focusNode == root)
root = null;
else if (isItALeftChild)
parent.leftChild = null;
else
parent.rightChild = null;
}
// one child ( left child )
else if (focusNode.rightChild == null) {
if (focusNode == root)
root = focusNode.leftChild;
else if (isItALeftChild)
parent.leftChild = focusNode.leftChild;
else
parent.rightChild = focusNode.leftChild;
}
else if (focusNode.leftChild == null) {
if (focusNode == root)
root = focusNode.rightChild;
else if (isItALeftChild)
parent.leftChild = focusNode.rightChild;
else
parent.rightChild = focusNode.rightChild;
}
// two children exits
else {
// replacement is the smallest node in the right subtree
// we neeed to delete the focusNode
Node replacement = getReplacementNode(focusNode);
if (focusNode == root)
root = replacement;
else if (isItALeftChild)
parent.leftChild = replacement;
else
parent.rightChild = replacement;
replacement.leftChild = focusNode.leftChild;
}
return true;
}
public Node getReplacementNode(Node replacedNode) {
Node replacementParent = replacedNode;
Node replacement = replacedNode;
Node focusNode = replacedNode.rightChild;
// find the smallest node of the right subtree of the node to be deleted
while (focusNode != null) {
replacementParent = replacement;
replacement = focusNode;
focusNode = focusNode.leftChild;
}
// exit when the focusNode is null
// the replacement is the smallest of the right subtree
if (replacement != replacedNode.rightChild) {
replacementParent.leftChild = replacement.rightChild;
replacement.rightChild = replacedNode.rightChild;
}
return replacement;
}
private void createMinimalBST(int arr[], int start, int end, Node newNode){
if ( end <= start ) return;
int mid = (start + end) / 2;
newNode.key = arr[mid];
// System.out.println("new node = "+ newNode );
if (start <= mid-1) {
if ( start < mid-1){
newNode.leftChild = new Node();
createMinimalBST( arr, start, mid - 1, newNode.leftChild );
}
else {
newNode.leftChild = new Node();
newNode.leftChild.key = arr[start];
}
}
if ( mid+1 <= end ) {
if ( mid+1 < end){
newNode.rightChild = new Node();
createMinimalBST(arr, mid + 1, end, newNode.rightChild);
}
else {
newNode.rightChild = new Node();
newNode.rightChild.key = arr[end];
}
}
// System.out.println("left child = "+ newNode.leftChild +" "+ " right child = "+ newNode.rightChild);
}
public static int getHeight(Node root) {
if (root == null) {
return 0;
}
return Math.max(getHeight(root.leftChild), getHeight(root.rightChild)) + 1;
}
public static boolean isBalanced( Node root) {
if (root == null) {
return true;
}
int heightDiff = getHeight(root.leftChild) - getHeight(root.rightChild);
if (Math.abs(heightDiff) > 1) {
return false;
}
else {
return isBalanced(root.leftChild ) && isBalanced(root.rightChild );
}
}
public void createMinimalBST(int array[]) {
// Node n = new Node();
Arrays.sort(array);
root = new Node();
createMinimalBST(array, 0, array.length - 1, root);
}
// create linked list of the same level of the tree
public static ArrayList<LinkedList<Node>> createLevelLinkedList( Node root) {
ArrayList<LinkedList<Node>> result = new ArrayList<LinkedList<Node>>();
/* "Visit" the root */
LinkedList<Node> current = new LinkedList<Node>();
if ( root != null) {
current.add(root);
}
while ( current.size() > 0) {
result.add(current); // Add previous level
LinkedList<Node> parents = current; // Go to next level
current = new LinkedList<Node>();
for ( Node parent : parents) {
/* Visit the children */
if (parent.leftChild != null) {
current.add(parent.leftChild);
}
if (parent.rightChild != null) {
current.add(parent.rightChild );
}
}
}
return result;
}
// print values in the same level of the tree gradually
public static void printResult(ArrayList<LinkedList<Node>> result){
int depth = 0;
for(LinkedList<Node> entry : result) {
Iterator<Node> i = entry.listIterator();
System.out.print("Link list at depth " + depth + ":");
while(i.hasNext()){
System.out.print(" " + ((Node)i.next()).key );
}
System.out.println();
depth++;
}
}
// using a key, check whether the node is inside of the BST or not
public boolean isBST (int n){
if ( n == root.key ){
return true;
}
else {
Node focusNode = root;
Node parent;
while( focusNode != null){
parent = focusNode;
if (focusNode != null){
if (n < focusNode.key){
focusNode = focusNode.leftChild;
}
else {
focusNode = focusNode.rightChild;
}
}
if ( focusNode != null && n == focusNode.key ){
return true;
}
}
}
return false;
}
//
public Node getNode (int n){
if ( n == root.key ){
return root;
}
else {
Node focusNode = root;
Node parent;
while( focusNode != null){
parent = focusNode;
if (focusNode != null){
if (n < focusNode.key){
focusNode = focusNode.leftChild;
}
else {
focusNode = focusNode.rightChild;
}
}
if ( focusNode != null && n == focusNode.key ){
return focusNode;
}
}
}
return null;
}
// get the parent of using the key of certain node
public Node getParent (int n){
if ( !isBST (n)){
return null;
}
if ( n == root.key ){
return null;
}
else {
Node focusNode = root;
Node parent;
while( focusNode != null){
parent = focusNode;
if (focusNode != null){
if (n < focusNode.key){
focusNode = focusNode.leftChild;
}
else {
focusNode = focusNode.rightChild;
}
}
if ( focusNode != null && n == focusNode.key ){
return parent;
}
}
}
return null;
}
/* get in-order successive node of the certain node */
public Node inorderSucc( Node n) {
if (n == null) return null;
// Found right children -> return left most node of right subtree
if ( getParent(n.key) == null || n.rightChild != null) {
return leftMostChild( n.rightChild );
}
else {
Node q = n;
Node x = getParent(q.key);
// Go up until we’re on left instead of right
while (x != null && x.leftChild != q) {
q = x;
x = getParent(x.key);
}
return x;
}
}
/* get the left most/ smallest node of the sub tree of the certain node */
public Node leftMostChild( Node n) {
if (n == null) {
return null;
}
while (n.leftChild != null) {
n = n.leftChild;
}
return n;
}
// SECOOND SOLUTION TO FIND OUT THE COMMON ANCESTOR OF TWO NODES
public static boolean covers2( Node root, Node p) {
if (root == null) return false;
if (root == p) return true;
return covers2(root.leftChild , p) || covers2(root.rightChild , p);
}
public static Node commonAncestorHelper( Node root, Node p, Node q) {
if (root == null) {
return null;
}
boolean is_p_on_left = covers2(root.leftChild , p);
boolean is_q_on_left = covers2(root.leftChild , q);
if (is_p_on_left != is_q_on_left) { // Nodes are on different side
return root;
}
// nodes are the same sides
Node child_side = is_p_on_left ? root.leftChild : root.rightChild;
return commonAncestorHelper(child_side, p, q);
}
public static Node commonAncestor2( Node root, Node p, Node q) {
if (!covers2(root, p) || !covers2(root, q)) { // Error check - one node is not in tree
return null;
}
return commonAncestorHelper(root, p, q);
}
// END OF THE SECOND SOLUTION
// FIRST SOLUTION TO FIND OUT THE COMMON ANCESTOR OF TWO NODES
// Checks how many “special” nodes are located under this root
public static int covers( Node root, Node p, Node q) {
int ret = NO_NODES_FOUND;
if (root == null) return ret;
if (root == p || root == q)
ret += 1;
ret += covers(root.leftChild , p, q);
if(ret == TWO_NODES_FOUND) // Found p and q
return ret;
return ret + covers(root.rightChild , p, q);
}
public static Node commonAncestor( Node root, Node p, Node q) {
if (q == p && (root.leftChild == q || root.rightChild == q))
return root;
int nodesFromLeft = covers(root.leftChild, p, q); // Check left side
if ( nodesFromLeft == TWO_NODES_FOUND ) {
if(root.leftChild == p || root.leftChild == q)
return root.leftChild;
else return commonAncestor(root.leftChild , p, q);
}
else if (nodesFromLeft == ONE_NODE_FOUND) {
if (root == p) return p;
else if (root == q) return q;
}
int nodesFromRight = covers(root.rightChild, p, q); // Check right side
if(nodesFromRight == TWO_NODES_FOUND) {
if(root.rightChild == p || root.rightChild == q)
return root.rightChild;
else return commonAncestor(root.rightChild , p, q);
}
else if (nodesFromRight == ONE_NODE_FOUND) {
if (root == p) return p;
else if (root == q) return q;
}
if (nodesFromLeft == ONE_NODE_FOUND &&
nodesFromRight == ONE_NODE_FOUND) return root;
else return null;
}
// END OF THE FIRST SOLUTION
// METHODS FOR SUBTREE CHECK
// Check if T2 is subtree of T1
public static boolean containsTree( Node t1, Node t2) {
if (t2 == null)
return true; // The empty tree is a subtree of every tree.
else
return subTree(t1, t2);
}
/* Checks if the binary tree rooted at r1 contains the binary tree
* rooted at r2 as a subtree somewhere within it.
*/
public static boolean subTree( Node r1, Node r2) {
if (r1 == null)
return false; // big tree empty & subtree still not found.
if (r1.key == r2.key) {
if (matchTree(r1,r2)) return true;
}
return (subTree(r1.leftChild , r2) || subTree(r1.rightChild , r2));
}
/*
Checks if the binary tree rooted at r1 contains the
binary tree rooted at r2 as a subtree starting at r1.
*/
public static boolean matchTree( Node r1, Node r2) {
if (r2 == null && r1 == null)
return true; // nothing left in the subtree
if (r1 == null || r2 == null)
return false; // big tree empty & subtree still not found
if (r1.key != r2.key)
return false; // data doesn’t match
return (matchTree(r1.leftChild, r2.leftChild) &&
matchTree(r1.rightChild , r2.rightChild ));
}
// END OF SUBTREE CHECK
/* Creates tree by mapping the array left to right, top to bottom. */
public Node createTreeFromArray(int[] array) {
if (array.length > 0) {
root = new Node(array[0]);
java.util.Queue<Node> queue = new java.util.LinkedList<Node>();
queue.add(root);
boolean done = false;
int i = 1;
while (!done) {
Node r = (Node) queue.element();
if (r.leftChild == null) {
r.leftChild = new Node(array[i]);
i++;
queue.add(r.leftChild);
}
else if (r.rightChild == null) {
r.rightChild = new Node(array[i]);
i++;
queue.add(r.rightChild );
}
else {
queue.remove();
}
if (i == array.length)
done = true;
}
return root;
}
else {
return null;
}
}
// ALGORITHM TO FIND ALL THE PATHS TO CERTAIN SUM VALUE
public static void findSum( Node node, int sum, int[] path, int level) {
if (node == null) {
return;
}
/* Insert current node into path */
path[level] = node.key;
int t = 0;
for (int i = level; i >= 0; i--){
t += path[i];
if (t == sum) {
print(path, i, level);
}
}
findSum( node.leftChild, sum, path, level + 1);
findSum( node.rightChild , sum, path, level + 1);
/* Remove current node from path. Not strictly necessary, since we would
* ignore this value, but it's good practice.
*/
path[level] = Integer.MIN_VALUE;
}
public static int depth( Node node) {
if (node == null) {
return 0;
}
else {
return 1 + Math.max(depth(node.leftChild), depth(node.rightChild));
}
}
public static void findSum( Node node, int sum) {
int depth = depth(node);
int[] path = new int[depth];
findSum(node, sum, path, 0);
}
private static void print(int[] path, int start, int end) {
for (int i = start; i <= end; i++) {
System.out.print(path[i] + " ");
}
System.out.println();
}
// END PATH ALGORITHM
public static void main(String[] args) {
int[] myArr = {5, 3, 1, 4, 8, 2, 6};
// int[] myArr = { 10,32,63,44,115,66,7,18,999 }; // sortedArrayToBST
BinaryTree myTr = new BinaryTree();
for( int j=0; j < myArr.length; j++){
myTr.addNode(myArr[j]);
}
// Node n = BinaryTree.createMinimalBST(myArr);
/*question 4-3
create a binary tree with minimal height ( balanced tree )*/
/*myTr.createMinimalBST(myArr);*/
// System.out.println("The root is = "+myTr.root);
myTr.inOrderTraverseTree(myTr.root);
System.out.println("\n\n");
/*get the height of the binary search tree*/
/*System.out.println( "the height of the tree is = "+myTr.height(myTr.root));
System.out.println("\n\n");*/
/*question 4-1
check whether the tree is balanced */
/*boolean isBalanced = myTr.isBalanced(myTr.root);
if (isBalanced) {
System.out.println("The tree is balanced \n\n");
}*/
/*question 4-4
create a linked list of all the nodes in the same level of the BST
breadth first search ( BFS ) is used for implementation */
/*ArrayList<LinkedList<Node>> list = createLevelLinkedList(myTr.root);
printResult(list);*/
/* ge parent of the elements */
/*
for(int j = 0; j < myArr.length ; j++){
int checkParent = myArr[j];
System.out.println("the parent of "+ checkParent +" is = "+ myTr.getParent( checkParent) );
}
*/
// using an integer value, get the node that contains that int element
/*Node myNode = myTr.getNode(44);
System.out.println("Get my node = "+ myNode.key ); */
/* get in-order successive node of certain node */
/*int getInOrderSuccessive = 44 ;
System.out.println( myTr.inorderSucc( myTr.getNode( getInOrderSuccessive)) );*/
/* question 4-6
get the first common ancestor of two nodes */
/*int firstNodeInteger = 7;
int secondNodeInteger = 66;
// try the first solution
System.out.println( myTr.commonAncestor( myTr.root, myTr.getNode(firstNodeInteger), myTr.getNode(secondNodeInteger) ));
// try the second solution
System.out.println( myTr.commonAncestor2( myTr.root, myTr.getNode(firstNodeInteger), myTr.getNode(secondNodeInteger) ));
*/
/* question 4-7 */
/* check whether one tree is sub-set of the another tree */
/*
int[] array1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int[] array2 = {2, 4, 5, 8, 9, 10, 11};
Node t1 = myTr.createTreeFromArray(array1);
Node t2 = myTr.createTreeFromArray(array2);
if (containsTree(t1, t2))
System.out.println("t2 is a subtree of t1");
else
System.out.println("t2 is not a subtree of t1");
int[] array3 = {1, 2, 3};
Node t3 = myTr.createTreeFromArray(array1);
Node t4 = myTr.createTreeFromArray(array3);
if (containsTree(t3, t4))
System.out.println("t4 is a subtree of t3");
else
System.out.println("t4 is not a subtree of t3");
*/
/* question 4-8
algorithm to get all the paths equal to given value */
/*int testValue = 7;
myTr.findSum( myTr.root, testValue );*/
}
}
Just use the root in your bbst() method instead of declaring n.
public void bbst(int array[]) {
root = new TreeNode();
balancedBST(array, 0, array.length - 1, root);
}
I can't see the balancedBST in your code. Did you mean the method createMinimalBST(int arr[], int start, int end, Node newNode)?
If so, then based on this call
createMinimalBST(array, 0, array.length - 1, root)
I deduce start and end parameters are inclusive indices of the subarray to be converted into a subtree. For the single-item array you have start == end — but then the first line of the method will discard that item:
if ( end <= start ) return;
leaving you with a new node with no key assigned.
And the whole method is overcomplicated and thus unreadable. KISS! For example:
private Node createBalancedTree(int arr[], int start, int end){
if ( end < start ) return null; // empty array -> empty tree
int mid = start + (end - start) / 2; // avoid overflow
// create a tip node
Node node = new Node( arr[mid] );
// convert remaining subarrays (if any) into subtrees
node.leftChild = createBalancedTree( arr, start, mid - 1 );
node.rightChild = createBalancedTree( arr, mid + 1, end );
return node;
}
public void createBalancedTree( int array[] ) {
// convert the array into a tree and plant it in this
root = createBalancedTree( array, 0, array.length - 1 );
}
Note however I removed 'BS' from the method name. The routine never checks the ordering of array items, so the resulting tree is balanced, but might be NOT-BST if the array isn't sorted!
If you want the resulting tree with a proper ordering you either need to sort the array prior to the 'build-a-tree' call or you have to add nodes one by one with an addNode(int key) method.
And if you want to build a balanced BST, then you need a new addNodeBalanced method...
(There is a load of other issues with your code, like a forever-recurring height(Node root), but I limit myself here to the part you pointed in your question.)
EDIT
The note about height(Node root) turned out to be false.
I am trying to implement a remove method for the BST structure that I have been working on. Here is the code with find, insert, and remove methods:
public class BST {
BSTNode root = new BSTNode("root");
public void insert(BSTNode root, String title){
if(root.title!=null){
if(title==root.title){
//return already in the catalog
}
else if(title.compareTo(root.title)<0){
if(root.leftChild==null){
root.leftChild = new BSTNode(title);
}
else{
insert(root.leftChild,title);
}
}
else if(title.compareTo(root.title)>0){
if(root.rightChild==null){
root.rightChild = new BSTNode(title);
}
else{
insert(root.rightChild,title);
}
}
}
}
public void find(BSTNode root, String title){
if(root!= null){
if(title==root.title){
//return(true);
}
else if(title.compareTo(root.title)<0){
find(root.leftChild, title);
}
else{
find(root.rightChild, title);
}
}
else{
//return false;
}
}
public void remove(BSTNode root, String title){
if(root==null){
return false;
}
if(title==root.title){
if(root.leftChild==null){
root = root.rightChild;
}
else if(root.rightChild==null){
root = root.leftChild;
}
else{
//code if 2 chlidren remove
}
}
else if(title.compareTo(root.title)<0){
remove(root.leftChild, title);
}
else{
remove(root.rightChild, title);
}
}
}
I was told that I could use the insert method to help me with the remove method, but I am just not seeing how I can grab the smallest/largest element, and then replace the one I am deleting with that value, then recursively delete the node that I took the replacement value, while still maintaining O(logn) complexity. Anyone have any ideas or blatant holes I missed, or anything else helpful as I bang my head about this issue?
EDIT:
I used the answers ideas to come up with this, which I believe will work but I'm getting an error that my methods (not just the remove) must return Strings, here is what the code looks like, I thought that's the return statements??
public String remove(BSTNode root, String title){
if(root==null){
return("empty root");
}
if(title==root.title){
if(root.leftChild==null){
if(root.rightChild==null){
root.title = null;
return(title+ "was removed");
}
else{
root = root.rightChild;
return(title+ "was removed");
}
}
else if(root.rightChild==null){
root = root.leftChild;
return(title+ "was removed");
}
else{
String minTitle = minTitle(root);
root.title = minTitle;
remove(root.leftChild,minTitle);
return(title+ "was removed");
}
}
else if(title.compareTo(root.title)<0){
remove(root.leftChild, title);
}
else{
remove(root.rightChild, title);
}
}
public void remove (String key, BSTNode pos)
{
if (pos == null) return;
if (key.compareTo(pos.key)<0)
remove (key, pos.leftChild);
else if (key.compareTo(pos.key)>0)
remove (key, pos.rightChild);
else {
if (pos.leftChild != null && pos.rightChild != null)
{
/* pos has two children */
BSTNode maxFromLeft = findMax (pos.leftChild); //need to make a findMax helper
//"Replacing " pos.key " with " maxFromLeft.key
pos.key = maxFromLeft.key;
remove (maxFromLeft.key, pos.leftChild);
}
else if(pos.leftChild != null) {
/* node pointed by pos has at most one child */
BSTNode trash = pos;
//"Promoting " pos.leftChild.key " to replace " pos.key
pos = pos.leftChild;
trash = null;
}
else if(pos.rightChild != null) {
/* node pointed by pos has at most one child */
BSTNode trash = pos;
/* "Promoting " pos.rightChild.key" to replace " pos.key */
pos = pos.rightChild;
trash = null;
}
else {
pos = null;
}
}
}
This is the remove for an unbalanced tree. I had the code in C++ so I have quickly translated. There may be some minor mistakes though. Does the tree you are coding have to be balanced? I also have the balanced remove if need be. I wasn't quite sure based on the wording of your question. Also make sure you add a private helper function for findMax()
void deleteTreeNode(int data){
root = deleteTreeNode(root ,data);
}
private TreeNode deleteTreeNode(TreeNode root, int data) {
TreeNode cur = root;
if(cur == null){
return cur;
}
if(cur.data > data){
cur.left = deleteTreeNode(cur.left, data);
}else if(cur.data < data){
cur.right = deleteTreeNode(cur.right, data);
}else{
if(cur.left == null && cur.right == null){
cur = null;
}else if(cur.right == null){
cur = cur.left;
}else if(cur.left == null){
cur = cur.right;
}else{
TreeNode temp = findMinFromRight(cur.right);
cur.data = temp.data;
cur.right = deleteTreeNode(cur.right, temp.data);
}
}
return cur;
}
private TreeNode findMinFromRight(TreeNode node) {
while(node.left != null){
node = node.left;
}
return node;
}
To compare objects in java use .equals() method instead of "==" operator
if(title==root.title)
^______see here
you need to use like this
if(title.equals(root.title))
or if you are interesed to ignore the case follow below code
if(title.equalsIgnoreCase(root.title))
private void deleteNode(Node temp, int n) {
if (temp == null)
return;
if (temp.number == n) {
if (temp.left == null || temp.right == null) {
Node current = temp.left == null ? temp.right : temp.left;
if (getParent(temp.number, root).left == temp)
getParent(temp.number, root).left = current;
else
getParent(temp.number, root).right = current;
} else {
Node successor = findMax(temp.left);
int data = successor.number;
deleteNode(temp.left, data);
temp.number = data;
}
} else if (temp.number > n) {
deleteNode(temp.left, n);
} else {
deleteNode(temp.right, n);
}
}
I know this is a very old question but anyways... The accepted answer's implementation is taken from c++, so the idea of pointers still exists which should be changed as there are no pointers in Java. So every time when you change the node to null or something else, that instance of the node is changed but not the original one This implementation is taken from one of the coursera course on algorithms.
public TreeNode deleteBSTNode(int value,TreeNode node)
{
if(node==null)
{
System.out.println("the value " + value + " is not found");
return null;
}
//delete
if(node.data>value) node.left = deleteBSTNode(value,node.left);
else if(node.data<value) node.right = deleteBSTNode(value,node.right);
else{
if(node.isLeaf())
return null;
if(node.right==null)
return node.left;
if(node.left==null)
return node.right;
TreeNode successor = findMax(node.left);
int data = successor.data;
deleteBSTNode(data, node.left);
node.data = data;
}
return node;
}
All the links between the nodes are pertained using the return value from the recursion.
For the Depth First Post-Order traversal and removal, use:
/*
*
* Remove uses
* depth-first Post-order traversal.
*
* The Depth First Post-order traversal follows:
* Left_Child -> Right-Child -> Node convention
*
* Partial Logic was implemented from this source:
* https://stackoverflow.com/questions/19870680/remove-method-binary-search-tree
* by: sanjay
*/
#SuppressWarnings("unchecked")
public BinarySearchTreeVertex<E> remove(BinarySearchTreeVertex<E> rootParameter, E eParameter) {
BinarySearchTreeVertex<E> deleteNode = rootParameter;
if ( deleteNode == null ) {
return deleteNode; }
if ( deleteNode.compareTo(eParameter) == 1 ) {
deleteNode.left_child = remove(deleteNode.left_child, eParameter); }
else if ( deleteNode.compareTo(eParameter) == -1 ) {
deleteNode.right_child = remove(deleteNode.right_child, eParameter); }
else {
if ( deleteNode.left_child == null && deleteNode.right_child == null ) {
deleteNode = null;
}
else if ( deleteNode.right_child == null ) {
deleteNode = deleteNode.left_child; }
else if ( deleteNode.left_child == null ) {
deleteNode = deleteNode.right_child; }
else {
BinarySearchTreeVertex<E> interNode = findMaxLeftBranch( deleteNode.left_child );
deleteNode.e = interNode.e;
deleteNode.left_child = remove(deleteNode.left_child, interNode.e);
}
} return deleteNode; } // End of remove(E e)
/*
* Checking right branch for the swap value
*/
#SuppressWarnings("rawtypes")
public BinarySearchTreeVertex findMaxLeftBranch( BinarySearchTreeVertex vertexParameter ) {
while (vertexParameter.right_child != null ) {
vertexParameter = vertexParameter.right_child; }
return vertexParameter; } // End of findMinRightBranch