Trying to search the binary search tree but there seems I cannot figure out why the there statement is not working, the method calls for the input of a String, but it says that a Node is required. Any suggestions how to fix this?
Here is the Node Class:
public class Node
{
String key;
Node left, right;
public Node(String entry)
{
key = entry;
left = right = null;
}
public Node getLeft()
{
return left;
}
public Node getRight()
{
return right;
}
public String getKey(String entry)
{
if(this.key.equals(key))
{
return key;
}
if(entry.compareTo(this.key) < 0)
{
return left == null ? null : left.getKey(entry);
}
else
{
return right == null ? null : right.getKey(entry);
}
}
public void setLeft(Node left)
{
this.left = left;
}
public void setRight(Node right)
{
this.right = right;
}
}
Here is my Binary Search Tree:
public class BinarySearchTree
{
Node root;
public BinarySearchTree()
{
root = null;
}
public void insert(String key)
{
root = insertRec(root, key);
}
public Node insertRec(Node root, String key)
{
if(root == null)
{
root = new Node(key);
return root;
}
if(key.compareTo(root.toString()) == -1)
{
root.setLeft(insertRec(root.getLeft(), key));
}
else if(key.compareTo(root.toString()) == 1)
{
root.setRight(insertRec(root.getRight(), key));
}
return root;
}
public Node search(String key)
{
return root == null ? null : root.getKey(key);
}
public void printPostOrder(Node node)
{
if(node == null)
return;
printPostOrder(root.getLeft());
printPostOrder(node.getRight());
System.out.print(node.getKey() + ", ");
}
public void printInOrder(Node node)
{
if(node == null)
return;
printInOrder(node.getLeft());
System.out.print(node.getKey() + ", ");
printInOrder(node.getRight());
}
public void printPreOrder(Node node)
{
if(node == null)
return;
System.out.print(node.getKey() + ", ");
printPreOrder(node.getLeft());
printPreOrder(node.getRight());
}
public void printPostOrder()
{
printPostOrder(root);
}
public void printInOrder()
{
printInOrder(root);
}
public void printPreOrder()
{
printPreOrder(root);
}
}
Any and all help is much appreciated if you need more information please let me know.
whats up ?
your code is wrong in the class node in method getKey change your return String to Node and your if equals and return to this.
Ex:.
public Node getKey(String entry)
{
if(this.key.equals(entry))
{
return this;
}
}
if you change this your code work.
Full class BinarySearchTree tested ok
public class BinarySearchTree
{
Node root;
public BinarySearchTree()
{
root = null;
}
public void insert(String key)
{
root = insertRec(root, key);
}
public Node insertRec(Node root, String key)
{
if(root == null)
{
root = new Node(key);
return root;
}
if(key.compareTo(root.toString()) == -1)
{
root.setLeft(insertRec(root.getLeft(), key));
}
else if(key.compareTo(root.toString()) == 1)
{
root.setRight(insertRec(root.getRight(), key));
}
return root;
}
public Node search(String key)
{
return root == null ? null : root.getKey(key);
}
public void printPostOrder(Node node)
{
if(node == null)
return;
printPostOrder(root.getLeft());
printPostOrder(node.getRight());
System.out.print(node.getKey("") + ", ");
}
public void printInOrder(Node node)
{
if(node == null)
return;
printInOrder(node.getLeft());
System.out.print(node.getKey("") + ", ");
printInOrder(node.getRight());
}
public void printPreOrder(Node node)
{
if(node == null)
return;
System.out.print(node.getKey("") + ", ");
printPreOrder(node.getLeft());
printPreOrder(node.getRight());
}
public void printPostOrder()
{
printPostOrder(root);
}
public void printInOrder()
{
printInOrder(root);
}
public void printPreOrder()
{
printPreOrder(root);
}
public static void main (String args[]){
BinarySearchTree bs = new BinarySearchTree();
bs.insert("A");
bs.search("A");
}
}
and Node complete
public class Node
{
String key;
Node left, right;
public Node(String entry)
{
key = entry;
left = right = null;
}
public Node getLeft()
{
return left;
}
public Node getRight()
{
return right;
}
public Node getKey(String entry)
{
if(this.key.equals(key))
{
return this;
}
if(entry.compareTo(this.key) < 0)
{
return left == null ? null : left.getKey(entry);
}
else
{
return right == null ? null : right.getKey(entry);
}
}
public void setLeft(Node left)
{
this.left = left;
}
public void setRight(Node right)
{
this.right = right;
}
}
Related
I am trying this code to populate the BST and then print it in the InOrder traversal format. But the root node is not getting populated compiling wihtout any error and Output is : "root is empty", so how to correct this code so that my BST gets populated in the Node root.
I tried to make Node root as static I thought it might be the case that root node might not be accessible from each method but it is not working, tried to change the name of the Node but it is also not working.
import java.util.*;
import java.io.*;
import java.lang.*;
class Node{
int data; Node left; Node right;
public Node(int data) {
this.data = data;
left = null;
right = null;
}
}
public class insert_tree {
static Node root;
insert_tree() //constructor
{
root = null;
}
public void addNode(int value) { // public method is called by the object and this public method calls the private method in which the root is also passed.
root = add(root, value);
}
private Node add(Node node, int value) {
if(node == null) {
return node;
}
if(value < node.data) {
node.left = add(node.left, value);
}
else if(value > node.data) {
node.right = add(node.right, value);
}
else {
return node;
}
return node;
}
private void inOrder(Node node) {
// node = root;
if(node != null) {
inOrder(node.left);
System.out.print(node.data + " ");
inOrder(node.right);
}
else {
System.out.print("root is empty");
}
//return null;
}
public void inorder() {
inOrder(root);
}
private void printRoot(Node root) {
System.out.println(root.data);
}
public void print() {
printRoot(root);
}
public static void main(String args[]) {
insert_tree obj = new insert_tree();
obj.addNode(20);
obj.addNode(14);
obj.addNode(25);
obj.addNode(10);
obj.addNode(16);
obj.addNode(25);
obj.addNode(21);
obj.addNode(30);
//printing the tree
obj.inorder();
}
}
The output should be the inorder traversal of the tree.
public void addNode(int value) { // public method is called by the object and this public method calls the private method in which the root is also passed.
root = add(root, value);
}
private Node add(Node node, int value) {
if(node == null) {
node = new Node(value);
}
else if(value == node.data) {
node.data = value;
}
else if(value < node.data) {
node.left = add(node.left, value);
}
else {
node.right = add(node.right, value);
}
return node;
}
I am tasked with building a BinaryTree that represents Morse Code. It branches left with each dot and right with each dash.
I can not figure out, however, why my method to add a Node does not seem to want to work with a BinaryTree object. IntelliJ says that it "can not resolve method".
I am certain that the BinaryTree is not the issue, because I was given detailed instructions on how to write the class by my instructor. Rather, I suspect that I am perhaps referencing the wrong thing here. I have already verified that the parameters being entered isn't the issue.
public static MorseCodeTree<Character> readMorseCodeTree()
{
MorseCodeTree<Character> morse = new MorseCodeTree<Character>();
Node<Character> newNode = new Node<Character>(null);
morse.addNode(newNode, letter, position);
private Node<Character> addNode(Node<Character> currentNode, char data, String morseCode)
{
if (currentNode == null)
{
currentNode = new Node(null);
}
if (morseCode.charAt(0) == '*')
{
currentNode = addNode(currentNode.left, data, morseCode.substring(1));
}
else if (morseCode.charAt(0) == '-')
{
currentNode = addNode(currentNode.right, data, morseCode.substring(1));
}
else
{
currentNode.data = data;
}
return currentNode;
}
BinaryTree class:
import java.io.Serializable;
import java.util.Scanner;
public class BinaryTree implements Serializable{
//implement Node class
protected static class Node<E> implements Serializable
{
protected E data;
protected Node<E> left;
protected Node<E> right;
public Node (E data)
{
this.data = data;
this.left = null;
this.right = null;
}
public String toString()
{
return data.toString();
}
}
protected Node root;
public BinaryTree()
{
root = null;
}
protected BinaryTree(Node<E> root)
{
this.root = root;
}
public BinaryTree(E data, BinaryTree<E> leftTree, BinaryTree<E> rightTree)
{
root = new Node<E>(data);
if (leftTree != null)
{
root.left = leftTree.root;
}
else
{
root.left = null;
}
if (rightTree != null)
{
root.right = rightTree.root;
}
else
{
root.right = null;
}
}
public BinaryTree<E> getLeftSubtree()
{
if (root != null && root.left != null)
{
return new BinaryTree<E>(root.left);
}
else
{
return null;
}
}
public BinaryTree<E> getRightSubtree()
{
if (root != null && root.right != null)
{
return new BinaryTree<E>(root.right);
}
else
{
return null;
}
}
public boolean isLeaf()
{
return (root.left == null && root.right == null);
}
public String toString()
{
StringBuilder sb = new StringBuilder();
preOrderTraverse(root, 1, sb);
return sb.toString();
}
private void preOrderTraverse(Node<E> node, int depth, StringBuilder sb)
{
for (int i = 1; i < depth; i++)
{
sb.append(" ");
}
if (node == null)
{
sb.append("null\n");
}
else
{
sb.append(node.toString() + "\n");
preOrderTraverse(node.left, depth + 1, sb);
preOrderTraverse(node.right, depth + 1, sb);
}
}
public static BinaryTree<String> readBinaryTree(Scanner scan)
{
String data = scan.next();
if (data.equals("null"))
{
return null;
}
else
{
BinaryTree<String> leftTree = readBinaryTree(scan);
BinaryTree<String> rightTree = readBinaryTree(scan);
return new BinaryTree<String>(data, leftTree, rightTree);
}
}
}
You're declaring the addNode(...) method within readMorseCodeTree(), so it's not in the scope of the class. The latter method should look like this:
public static BinaryTree<Character> readMorseCodeTree()
{
BinaryTree morse = new MorseCodeTree();
Node<Character> newNode = new Node<Character>(null);
morse.addNode(newNode, letter, position);
}
I'm trying to create binary tree by following example 1 where tree is made without getters and setters. I would like to create it with geeters and setters but I'm stuck on line with recursion. How can I call recursion function with/inside setter? Here is the code..
p.s. Tree class pastebin
public class TreeF {
Tree root;
public void insert(int value) {
if (root==null) {
root = new Tree(value);
return;
}
Tree current = root;
if (value < current.getData() ) {
if (current.getLeft()==null) {
current.setLeft(new Tree (value));
}else {
// call insert method inside current.left object [currrent.left(insert(value))]
current=current.getLeft();
insert (value);
}
}
else {
if (current.getRight()==null) {
current.setRight(new Tree (value));
}else {
current=current.getRight();
insert (value);
}
}
}
}
Change insert(value) to current.insert(value)
To implement recursion, you need to change a parameter(or multiple) so you can go to the stopping condition after some recursive calls.
In your code, you called the method insert that was part of the same object. And not its left/right subtree. In other words, the recursion never ends, because you don't visit the child subtrees.
public class Tree {
private int data;
private Tree left;
private Tree right;
public Tree (int data) {
this.data=data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Tree getLeft() {
return left;
}
public void setLeft(Tree left) {
this.left = left;
}
public Tree getRight() {
return right;
}
public void setRight(Tree right) {
this.right = right;
}
public void insert(int value) {
if (value < getData()) {
if (getLeft() == null) {
setLeft(new Tree(value));
} else {
getLeft().insert(value);
}
} else {
if (getRight() == null) {
setRight(new Tree(value));
} else {
getLeft().insert(value);
}
}
}
}
You do not need a current field or a root. Here's your insert method greatly simplified to demonstrate.
public class Tree {
final int data;
Tree left;
Tree right;
public Tree(int value) {
data = value;
}
public void insert(int value) {
if (value < data) {
if (left == null) {
left = new Tree(value);
} else {
left.insert(value);
}
} else {
if (right == null) {
right = new Tree(value);
} else {
right.insert(value);
}
}
}
}
I have implemented a Binary search tree with insert and traversal method but am not getting correct output for PreOrder and Postorder ,am getting inOrder in correct order. Could some one please tell me where am wrong.
I tried the same example on paper but the PreOrder and PostOrder is not same.
Here is my Code
Node Class
package com.BSTTest;
public class Node implements Comparable<Node> {
private int data;
private Node leftChild;
private Node rightChild;
public Node(int data) {
this(data, null, null);
}
public Node(int data, Node leftChild, Node rightChild) {
this.data = data;
this.leftChild = leftChild;
this.rightChild = rightChild;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLeftChild() {
return leftChild;
}
public void setLeftChild(Node leftChild) {
this.leftChild = leftChild;
}
public Node getRightChild() {
return rightChild;
}
public void setRightChild(Node rightChild) {
this.rightChild = rightChild;
}
public int compareTo(Node o) {
return Integer.compare(this.data, o.getData());
}
}
Tree Class
package com.BSTTest;
import com.BSTTest.Node;
public class Tree {
private Node root = null;
public Node getRoot() {
return root;
}
//Inserting data**strong text**
public void insertData(int data) {
Node node = new Node(data, null, null);
if (root == null) {
root = node;
} else {
insert(node, root);
}
}
//Helper method for insert
private void insert(Node node, Node currNode) {
if (node.compareTo(currNode) < 0) {
if (currNode.getLeftChild() == null) {
currNode.setLeftChild(node);
} else {
insert(node, currNode.getLeftChild());
}
} else {
if (currNode.getRightChild() == null) {
currNode.setRightChild(node);
} else {
insert(node, currNode.getRightChild());
}
}
}
public void printInorder() {
printInOrderRec(root);
System.out.println("");
}
//Helper method to recursively print the contents in an inorder way
private void printInOrderRec(Node currRoot) {
if (currRoot == null) {
return;
}
printInOrderRec(currRoot.getLeftChild());
System.out.print(currRoot.getData() + ", ");
printInOrderRec(currRoot.getRightChild());
}
public void printPreorder() {
printPreOrderRec(root);
System.out.println("");
}
// Helper method for PreOrder Traversal recursively
private void printPreOrderRec(Node currRoot) {
if (currRoot == null) {
return;
}
System.out.print(currRoot.getData() + ", ");
printPreOrderRec(currRoot.getLeftChild());
printPreOrderRec(currRoot.getRightChild());
}
public void printPostorder() {
printPostOrderRec(root);
System.out.println("");
}
/**
* Helper method for PostOrder method to recursively print the content
*/
private void printPostOrderRec(Node currRoot) {
if (currRoot == null) {
return;
}
printPostOrderRec(currRoot.getLeftChild());
printPostOrderRec(currRoot.getRightChild());
System.out.print(currRoot.getData() + ", ");
}
//Main Mthod
public static void main(String[] args) {
Tree obj = new Tree();
//Inserting data
obj.insertData(3);
obj.insertData(5);
obj.insertData(6);
obj.insertData(2);
obj.insertData(4);
obj.insertData(1);
obj.insertData(0);
//printing content in Inorder way
System.out.println("Inorder traversal");
obj.printInorder();
//printing content in Inorder way
System.out.println("Preorder Traversal");
obj.printPreorder();
//printing content in Inorder way
System.out.println("Postorder Traversal");
obj.printPostorder();
}
}
Look my friend,your code is absolutely fine as the outputs you mentioned are absolutely correct.
I think you have not understood the concept of Binary Search Tree correctly.
You are right,3 is root node but you wrong in saying that 1 is its left child.
The first value that appears after 3 and that is smaller than 3 is 2,therefore 2 is left child of 3 and not 1
Refer to Cormenn book if still there is confusion.
I'm trying to write an implementation of a BinaryTree whose object can be of any type that implements Comparable. However, I realize that won't completely work. For example, A String and a Double wouldn't be able to be inserted into the same tree, even though they both implement Comparable.
So, I would like to know if it's possible to write the code such that the BinaryTree can be instantiated with any value whose type implements Comparable, but any ensuing elements added to the tree must all share the same supertype as the root's value.
Here's the code I have so far:
public class BinaryTree {
private Node root;
public BinaryTree() {
this.root = null;
}
public Node lookup(Comparable<Object> value) {
return lookup(this.root, value);
}
private Node lookup(Node node, Comparable<Object> value) {
Node match = null;
if (match != node) {
if (value == node.value) {
match = node;
} else if (value.compareTo(node.value) < 0) {
return lookup(node.left, value);
} else {
return lookup(node.right, value);
}
}
return match;
}
public Node lookupNonRecursively(Comparable<Object> value) {
return lookupNonRecursively(this.root, value);
}
private Node lookupNonRecursively(Node node, Comparable<Object> value) {
Node match = null;
if (match != node) {
if (value == node.value) {
match = node;
} else {
Node root = node;
boolean found = false;
while (!found && root != null) {
if (root.value.compareTo(value) < 0) {
if (root.left == null) {
root.left = match = new Node(value);
found = true;
} else {
root = root.left;
}
} else {
if (root.right == null) {
root.right = match = new Node(value);
found = true;
} else {
root = root.right;
}
}
}
}
}
return match;
}
public Node insert(Comparable<Object> value) {
return insert(this.root, value);
}
private Node insert(Node node, Comparable<Object> value) {
if (node == null) {
node = new Node(value);
} else {
if (node.value.compareTo(value) <= 0) {
insert(node.left, value);
} else {
insert(node.right, value);
}
}
return node;
}
public Node insertNonRecursively(Comparable<Object> value) {
return insertNonRecursively(this.root, value);
}
private Node insertNonRecursively(Node node, Comparable<Object> value) {
if (node == null) {
node = new Node(value);
} else {
Node root = node;
boolean inserted = false;
while (!inserted) {
if (node.value.compareTo(root.value) < 0) {
if (root.left == null) {
root.left = node = new Node(value);
inserted = true;
} else {
root = root.left;
}
} else {
if (root.right == null) {
root.right = node = new Node(value);
inserted = true;
} else {
root = root.right;
}
}
}
}
return node;
}
public static class Node {
private Node left;
private Node right;
private Comparable<Object> value;
public Node(Comparable<Object> value) {
this.left = null;
this.right = null;
this.value = value;
}
}
}
And as a test, this will throw the error, The method insert(Comparable<Object>) in the type BinaryTree is not applicable for the arguments (Integer), if I try to run code like the following:
BinaryTree tree = new BinaryTree();
tree.insert(new Integer(1));
You can see I've implemented some different BinaryTree methods for this class, but the same rules would need to apply: any value passed into lookup() or insert() would also need to share the root's supertype. I have a feeling this is where some variant of <T extends Comparable<? super T>> is going to come into play, but my mind is just not figuring this one out.
Any ideas for how I might accomplish this?
As noted by #jp-jee, here's my solution (also with logic and other bugs fixed from untested first attempt), which works beautifully:
public class BinaryTree<T extends Comparable<T>> {
private Node<T> root;
public BinaryTree() {
this.root = null;
}
public Node<T> lookup(T value) {
return lookup(this.root, value);
}
private Node<T> lookup(Node<T> node, T value) {
Node<T> match = null;
if (match != node) {
if (value.equals(node.value)) {
match = node;
} else if (value.compareTo(node.value) < 0) {
return lookup(node.left, value);
} else {
return lookup(node.right, value);
}
}
return match;
}
public Node<T> lookupNonRecursively(T value) {
return lookupNonRecursively(this.root, value);
}
private Node<T> lookupNonRecursively(Node<T> node, T value) {
Node<T> match = null;
if (match != node && value != null) {
if (value.equals(node.value)) {
match = node;
} else {
Node<T> searchRoot = node;
boolean found = false;
while (!found && searchRoot != null) {
if (value.equals(searchRoot.value)) {
match = searchRoot;
found = true;
} else if (value.compareTo(searchRoot.value) < 0) {
searchRoot = searchRoot.left;
} else {
searchRoot = searchRoot.right;
}
}
}
}
return match;
}
public void insert(T value) {
this.root = insert(this.root, value);
}
private Node<T> insert(Node<T> node, T value) {
if (node == null) {
node = new Node<T>(value);
} else {
if (value.compareTo(node.value) <= 0) {
node.left = insert(node.left, value);
} else {
node.right = insert(node.right, value);
}
}
return node;
}
public void insertNonRecursively(T value) {
this.root = insertNonRecursively(this.root, value);
}
private Node<T> insertNonRecursively(Node<T> node, T value) {
if (node == null) {
node = new Node<T>(value);
} else {
Node<T> runner = node;
boolean inserted = false;
while (!inserted) {
if (value.compareTo(runner.value) < 0) {
if (runner.left == null) {
runner.left = new Node<T>(value);
inserted = true;
} else {
runner = runner.left;
}
} else {
if (runner.right == null) {
runner.right = new Node<T>(value);
inserted = true;
} else {
runner = runner.right;
}
}
}
}
return node;
}
public static class Node<T extends Comparable<T>> {
private Node<T> left;
private Node<T> right;
private T value;
public Node(T value) {
this.left = null;
this.right = null;
this.value = value;
}
public Node<T> getLeft() {
return left;
}
public Node<T> getRight() {
return right;
}
public T getValue() {
return value;
}
}
}
Make your Binary Tree generic like
public class BinaryTree<T extends Comparable<T>>{
...
}
Whenever creating a BinaryTree instance, specify the containied type:
new BinaryTree<MyClass>();
Where MyClass must implement Comparable<MyClass>, i.e. be comparable to Objects of the same class.
Your methods would read as (example):
public Node lookup(T value) { ... }
The same applies for your Node class. Make it generic the same way.