How to remove a string from a Binary Search Tree - java

I am trying to remove a string from a BST and I cannot figure it out. I know how to remove integers but cannot convert my code to remove Nodes that have strings. Here is the code I currently have
/*
* Removes the specified string from the BST
*/
public boolean remove(String s){
Node ans = remove(root, s);
if(ans == null){
return false;
} else {
return true;
}
}
private static Node remove(Node root, String s) {
if (root == null)
return null;
if (s.compareTo(root.data) < 0) {
root.left = remove(root.left, s);
} else if (s.compareTo(root.data) > 0) {
root.right = remove(root.right, s);
} else {
if (root.left == null) {
return root.right;
} else if (root.right == null)
return root.left;
root.data = minimum(root.right);
root.right = remove(root.right, root.data);
}
return root;
}
public static String minimum(Node root) {
String minimum = root.data;
while (root.left != null) {
minimum = root.left.data;
root = root.left;
}
return minimum;
}

Replace all "Integer" with "String" .

I know this was 2 years ago but I case someone needs help I did this instead..
private String minimum(BSTNode treeRoot) {
String minimum = treeRoot.value;
while (treeRoot.left != null) {
minimum = treeRoot.left.value;
treeRoot = treeRoot.left;
}
return minimum;
}
private BSTNode removeValue(BSTNode treeRoot, String s){
if(treeRoot == null){
return treeRoot;
} else if(s.compareTo(treeRoot.value) < 0){
treeRoot.left = removeValue(treeRoot.left, s);
} else if(s.compareTo(treeRoot.value) > 0){
treeRoot.right = removeValue(treeRoot.right, s);
} else {
if(treeRoot.left == null){
return treeRoot.right;
} else if(treeRoot.right == null){
return treeRoot.left;
}
treeRoot.value = minimum(treeRoot.right);
treeRoot.right = removeValue(treeRoot.right, treeRoot.value);
}
return treeRoot;
}

Related

writing a proper binary tree height function?

I'm trying to write a function that displays the height of my binary search tree which is displayed below. The problem is I'm supposed to write a function that doesn't have any arguments or parameters. This is really stumping me. I tried declaring root outside the parameter list but that didn't work. Any solutions?
int height (Node root){
if (root == null) {
return 0;
}
int hleftsub = height(root.m_left);
int hrightsub = height(root.m_right);
return Math.max(hleftsub, hrightsub) + 1;
}
the method signature provide by my instructor is
int height ()
EDIT:
my full code
import javax.swing.tree.TreeNode;
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.File;
import java.util.ArrayList;
class BinarySearchTree<E extends Comparable<E>> {
public Node<E> root;
public int m_size = 0;
public BinarySearchTree() {
}
public boolean search(E value) {
boolean ret = false;
Node<E> current = root;
while (current != null && ret != true) {
if (current.m_value.compareTo(current.m_value) == 0) {
ret = true;
} else if (current.m_value.compareTo(current.m_value) > 0) {
current = current.m_left;
} else {
current = current.m_right;
}
}
return false;
}
public boolean insert(E value) {
if (root == null) {
root = new Node<>(value);
m_size++;
} else {
Node<E> current = root;
Node<E> parentNode = null;
while (current != null)
if (current.m_value.compareTo(value) > 0) {
parentNode = current;
current = current.m_left;
} else if (current.m_value.compareTo(value) < 0) {
parentNode = current;
current = current.m_right;
} else {
return false;
}
if (current.m_value.compareTo(value) < 0) {
parentNode.m_left = new Node<>(value);
} else {
parentNode.m_right = new Node<>(value);
}
}
m_size++;
return true;
}
boolean remove(E value) {
if (!search(value)) {
return false;
}
Node check = root;
Node parent = null;
boolean found = false;
while (!found && check != null) {
if (value.compareTo((E) check.m_value) == 0) {
found = true;
} else if (value.compareTo((E) check.m_value) < 0) {
parent = check;
check = check.m_left;
} else {
parent = check;
check = check.m_right;
}
}
if (check == null) {
return false;
} else if (check.m_left == null) {
if (parent == null) {
root = check.m_right;
} else if (value.compareTo((E) parent.m_value) < 0) {
parent.m_left = check.m_right;
} else {
parent.m_right = check.m_right;
}
} else {
Node<E> parentofRight = check;
Node<E> rightMost = check.m_left;
while (rightMost.m_right != null) {
parentofRight = rightMost;
rightMost = rightMost.m_right;
}
check.m_value = rightMost.m_value;
if (parentofRight.m_right == rightMost) {
rightMost = rightMost.m_left;
} else {
parentofRight.m_left = rightMost.m_left;
}
}
m_size--;
return true;
}
int numberNodes () {
return m_size;
}
int height (Node root){
if (root == null) {
return 0;
}
int hleftsub = height(root.m_left);
int hrightsub = height(root.m_right);
return Math.max(hleftsub, hrightsub) + 1;
}
int numberLeafNodes(Node node){
if (node == null) {
return 0;
}
else if(node.m_left == null && node.m_right == null){
return 1;
}
else{
return numberLeafNodes(node.m_left) + numberLeafNodes(node.m_right);
}
}
void display(String message){
if(root == null){
return;
}
display(String.valueOf(root.m_left));
display(String.valueOf(root));
display(String.valueOf(root.m_right));
}
}
class Node<E> {
public E m_value;
public Node<E> m_left;
public Node<E> m_right;
public Node(E value) {
m_value = value;
}
}
If you traverse the tree iteratively, you can get the height without recursion. Anything recursive can be implemented iteratively. It may be more lines of code though. This would be a variation of level order graph / tree traversal.
See: https://www.geeksforgeeks.org/iterative-method-to-find-height-of-binary-tree/
If you use that implementation, delete the parameter, as height() will already have access to root.
This however requires a queue and is O(n) time and O(n) space.
height() may be a public method that calls a private method height(Node node) that starts recursion. O(n) time, O(1) space for BST.
You can pass height as an extra parameter where recursively inserting into the tree so that you are counting the number of recursive calls (which is directly correlated with the depth / # of levels down in the tree you are). Once a node finds it's place, if the height (# of recursive calls) you were passing exceeds the instance variable height stored by the tree, you update the instance variable to the new height. This will also allow tree.height() to be a constant time function. O(1) time, O(1) space.

Binary Search Tree - print out number of leaves

I have a program that is a binary search tree, the method searches for a specific word. I'm having two problems.
First is I would like to print the true or false from this method (basically making a system.out that says if the word was found), I'm assuming I would do it in main but I'm not sure how to do that.
The second problem is that I also need to print out how many leaves are in the tree, I was going to use a counter of some sort in the method but I didn't work.
My method is below but I also included it inside the class to help clear up any confusion.
Any help would be greatly appreciated.
public boolean check(BSTNode t,String key)
{
if (t == null) return false;
if (t.word.equals(key)) return true;
if (check(t.left,key)) return true;
if (check(t.right,key)) return true;
return false;
}
Whole class:
public class BST
{
BSTNode root;
BST() {
root = null;
}
public void add2Tree(String st)
{
BSTNode newNode = new BSTNode(st);
if (this.root == null) {
root = newNode;
} else {
root = addInOrder(root, newNode);
}
}
// private BSTNode insert2(BSTNode root, BSTNode newNode)
// {
// if (root == null)
// root = newNode;
// else {
// System.out.println(root.word + " " + newNode.word);
// if (root.word.compareTo(newNode.word) > 0)
// {
// root.left = (insert2(root.lTree, newNode));
// System.out.println(" left ");
// } else
// {
// root.rTree = (insert2(root.rTree, newNode));
// System.out.println(" right ");
// }
// }
// return root;
// }
public BSTNode addInOrder(BSTNode focus, BSTNode newNode) {
int comparevalue = 0;
if (focus == null) {
focus = newNode;
}
if (focus != null) {
comparevalue = newNode.word.compareTo(focus.word);
}
if (comparevalue < 0) {
focus.left = addInOrder(focus.left, newNode);
} else if (comparevalue > 0) {
focus.right = addInOrder(focus.right, newNode);
}
return (focus);
}
public void ioprint() {
System.out.println(" start inorder");
if (root == null)
System.out.println(" Null");
printinorder(root);
}
public void printinorder(BSTNode t) {
if (t != null) {
printinorder(t.left);
System.out.println(t.word);
printinorder(t.right);
}
}
public boolean check(BSTNode t,String key)
{
if (t == null) return false;
if (t.word.equals(key)) return true;
if (check(t.left,key)) return true;
if (check(t.right,key)) return true;
return false;
}
public BSTNode getroot(){
return root;
}
}
How to print true/false:
Create another class, call it Solution, Test or whatever you like.
Add a main method to it.
Populate your BST.
Call System.out.println(check(bstRoot, key)).
You can check this link to find out how to count the number of nodes in BST, it's pretty straightforward:
Counting the nodes in a binary search tree
private int countNodes(BSTNode current) {
// if it's null, it doesn't exist, return 0
if (current == null) return 0;
// count myself + my left child + my right child
return 1 + nodes(current.left) + nodes(current.right);
}

binary search tree deletion method [duplicate]

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

java binary tree insert function non recursive

I have written a code for inserting to the binary tree an element generic's type which is ordered by their names. Don't think it is correct though.
public boolean insert(E e) {
BTNode temp = root;
if (root == null) {
root.setElement(e);
}
while (temp != null)
if (temp.element().getClass().getName().compareTo(e.getClass().getName()) < 0) {
temp = temp.getRight();
} else {
temp = temp.getLeft();
}
temp.setElement(e);
return true;
}
Can you suggest me corrections ?
An insert would need to create a new node. I don't now how to create them as I haven't see the constuctor, but I suggest something along the lines of:
public boolean insert(E e) {
if (root == null) {
root = new BTNode();
root.setElement(e); //how would this work with a null root?
return true; //that's it, we're done (when is this ever false by the way?)
}
BTNode current = root;
while (true) { //brackets! indenting is important for readabilty
BTNode parent=current;
if (current.element().getClass().getName().compareTo(e.getClass().getName()) < 0) {
current = current.getRight();
if(current==null) { //we don't have a right node, need to make one
current = new BTNode();
parent.setRight(current);
break; //we have a new node in "current" that is empty
}
} else {
current= current.getLeft();
if(current==null) { //we don't have a left node, need to make one
current = new BTNode();
parent.setLeft(current);
break; //we have a new node in "current" that is empty
}
}
}
current.setElement(e);
return true;
}
public Boolean add(int data){
Node node = new Node(data);
if(isEmpty()){
root = node;
}else{
Node temp = root;
while(true){
if(data < temp.getData()){
if(temp.getLeft() != null)
temp = temp.getLeft();
else
break;
}else{
if(temp.getRight() != null)
temp = temp.getRight();
else
break;
}
}
if(data < temp.getData())
temp.setLeft(node);
else
temp.setRight(node);
}
return true;
}
As amadeus mentioned, the while loop should not have a semicolon at the end :
BTNode temp = root;
if (root == null) {
root.setElement(e);
return;
}
while (temp != null)
{
if (temp.element().getClass().getName().compareTo(e.getClass().getName()) < 0) {
if(temp.getRight() != null)
temp = temp.getRight();
else
{
temp.createRight(e);
temp = null; //or break
}
} else {
if(temp.getLeft() != null)
temp = temp.getLeft();
else
{
temp.createLeft(e);
temp = null; //or break
}
}
}
return true;

Printing Ancestors of a node in Binary Tree

I need to print the ancestors of a node in binary tree. e.g Node 7 has ancestors as 1,3 . I have written the below code but output is coming as 7. Can you suggest the issues in this code?
1
/ \
2 3
/ \ / \
4 5 6 7
public static String findAncestor(BinaryTreeNode root , int number, boolean matched) {
if (root != null) {
int rootData = root.getData();
BinaryTreeNode left = root.getLeft();
BinaryTreeNode right = root.getRight();
if (left != null && right != null) {
return findAncestor (root.getLeft(), number, matched ) + findAncestor (root.getRight(), number, matched);
}
if (left != null) {
return findAncestor (root.getLeft(), number, matched ) ;
}
if (right != null) {
return findAncestor (root.getRight(), number, matched ) ;
}
if (rootData == number) {
matched = true;
return String.valueOf(rootData);
}
if (matched) {
return String.valueOf(rootData);
}
}
return "";
}
public boolean findAncestorPath(List<Integer> ancestors, BinaryTreeNode node, int number) {
if (node == null)
return false;
int data = node.getData();
if (data == number)
return true;
if (findAncestorPath(ancestors, node.getLeft(), number)) {
ancestors.add(data);
return true;
}
if (findAncestorPath(ancestors, node.getRight(), number)) {
ancestors.add(data);
return true;
}
return false;
}
Then you'd call this as (you should also probably wrap it in a function):
List<Integer>() ancestors = new ArrayList<Integer>();
boolean found = findAncestorPath(ancestors, root, number);
Note that the ancestor list would be reversed.
Here is the Java implementation
public static List<Integer> ancestors(BinaryTreeNode<Integer> root, Integer target) {
List<Integer> result = new ArrayList<Integer>();
findAncestors(root, target, result);
return result;
}
private static boolean findAncestors(BinaryTreeNode<Integer> node, Integer target, List<Integer> result) {
if (node == null) {
return false;
}
if (node.getData() == target) {
return true;
}
if (findAncestors(node.getLeft(), target, result) || findAncestors(node.getRight(), target, result)) {
result.add(node.getData());
return true;
}
return false;
}
Here is the unit test case
#Test
public void allAncestors() {
BinaryTreeNode<Integer> root = buildTree();
List<Integer> ancestors = BinaryTreeUtil.ancestors(root, 6);
assertThat(ancestors.toArray(new Integer[0]), equalTo(new Integer[]{5,2,1}));
}
This piece of code work fine for giving all the ancestors a particular node , node is root node and value is the value of the node for which we have to find all the ancestor.
static boolean flag=false;
static void AnchersterOf(AnchesterNode node,int value) {
// TODO Auto-generated method stub
if(node==null)
return ;
if(node.value==value){
flag=true;
return;
}
if(flag==false){
AnchersterOf(node.left,value);
if(flag==true){
AnchersterOf(node,value);
} if(flag==true)
System.out.println(node.value);
AnchersterOf(node.right,value);
if(flag==true)
System.out.println(node.value);
}
}

Categories

Resources