I am currently in an intro data structures class and am really struggling with one of our problems about Binary Search Trees. This is the first time I have implemented this data structure and am doing my best to learn it.
Problem:
The program is supposed to create and search a BST of name and occurrence data, based upon the census data of babies born that year. We are given this data in a txt file.
I am having a lot of difficulty figuring out why it is not working. I am really just looking for someone to lead me in the right direction from here and give me some good feedback on what I already have because I feel really lost! My current work is below. I am implementing this in java. Thanks in advance!
public class Node {
String name;
int data;
Node leftChild;
Node rightChild;
public Node (String n, int d) {
name = n;
data = d;
}
public class BinarySearchTree` {
public static Node root;
public void addNode(String name, int data) {
Node newNode = new Node(name, data);
if (root == null) {
root = newNode;
} else {
Node focusNode = root;
Node parent;
while(true) {
parent = focusNode;
if (name.compareTo(focusNode.name) < 0) {
focusNode = focusNode.leftChild;
if (focusNode == null) {
parent.leftChild = newNode;
return;
} else {
focusNode = focusNode.rightChild;
if (focusNode == null) {
parent.rightChild = newNode;
return;
}
}
}
}
}
}
public Node searchName(String name) {
Node focusNode = root;
while (!focusNode.name.equals(name)) {
if (name.compareTo(focusNode.name) < 0) {
focusNode = focusNode.leftChild;
} else {
focusNode = focusNode.rightChild;
}
if (focusNode == null) {
return null;
}
}
return focusNode;
}
public static void main(String[] args) throws Exception {
BinarySearchTree tree = new BinarySearchTree();
FileReader file = new FileReader("/Users/mattspahr/Desktop/test.txt");
BufferedReader reader = new BufferedReader(file);
String str = null,
name = null,
num = null;
int data;
while(reader.readLine() != null) {
str = reader.readLine();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c >= '0' || c <= '9') {
name = str.substring(0, i);
}
num = str.replaceAll("[^0-9]" , "");
}
data = Integer.parseInt(num);
tree.addNode(name,data);
Node n = tree.searchName("Buffy ");
System.out.println(n);
}
}
}
Related
Im trying to implement a program that adds Word Objects(string word, string meaning) into a Binary Search Tree Alphabetically. I know how to implement a Binary Search Tree with an integer attribute but I'm having difficulties doing it with strings.
public class WordInfo {
public String word;
public String meaning;
public WordInfo left;
public WordInfo right;
public WordInfo(String word, String meaning){
this.word = word;
this.meaning = meaning;
left=right = null;
}
}
public class Dictionary {
WordInfo root;
int count;
public Dictionary() {
root = null;
}
public void add(String word, String meaning) {
WordInfo w = new WordInfo(word, meaning);
if (root == null) {
root = w;
}
WordInfo curr, parent;
parent = curr = root;
while (curr != null) {
parent = curr;
if (word.compareToIgnoreCase(curr.word) < 0) {
curr = curr.left;
} else {
curr = curr.right;
}
}
if (word.compareToIgnoreCase(parent.word) < 0) {
parent.left = w;
} else {
parent.right = w;
}
} }
When I try to add these WordInfo objects into my main program nothing is being added.
In your code snippet, you haven't returned if empty dictionary.
if (root == null) {
root = w;
}
have to be replaced with
if (root == null) {
root = w;
return;
}
So if the root is null, you add an element and return it, of course you can increment the count when new element added.
hi im new to codings and i have to print my binary search tree in a 2d model but this codes only print the orders of number in order(left-root-right) such as when i insert 10, 9, 11, 8, it will print inorder (left root right) = 8,9,10,11. what method or codes should i add to create a 2d tree here. sorry idk how to properly put the codes here just look at it like it is only a one code only.
class binarySearchTree {
class Node {
int key;
Node left, right;
int data;
public Node(int data){
key = data;
left = right = null;
}
}
// BST root node
Node root;
// Constructor for BST =>initial empty tree
binarySearchTree(){
root = null;
}
//delete a node from BST
void deleteKey(int key) {
root = delete_Recursive(root, key);
}
//recursive delete function
Node delete_Recursive(Node root, int key) {
//tree is empty
if (root == null) return root;
//traverse the tree
if (key < root.key) //traverse left subtree
root.left = delete_Recursive(root.left, key);
else if (key > root.key) //traverse right subtree
root.right = delete_Recursive(root.right, key);
else {
// node contains only one child
if (root.left == null)
return root.right;
else if (root.right == null)
return root.left;
// node has two children;
//get inorder successor (min value in the right subtree)
root.key = minValue(root.right);
// Delete the inorder successor
root.right = delete_Recursive(root.right, root.key);
}
return root;
}
int minValue(Node root) {
//initially minval = root
int minval = root.key;
//find minval
while (root.left != null) {
minval = root.left.key;
root = root.left;
}
return minval;
}
// insert a node in BST
void insert(int key) {
root = insert_Recursive(root, key);
}
//recursive insert function
Node insert_Recursive(Node root, int key) {
//tree is empty
if (root == null) {
root = new Node(key);
return root;
}
//traverse the tree
if (key < root.key) //insert in the left subtree
root.left = insert_Recursive(root.left, key);
else if (key > root.key) //insert in the right subtree
root.right = insert_Recursive(root.right, key);
// return pointer
return root;
}
void inorder() {
inorder_Recursive(root);
}
// recursively traverse the BST
void inorder_Recursive(Node root) {
if (root != null) {
inorder_Recursive(root.left);
System.out.print(root.key + " x ");
inorder_Recursive(root.right);
}
}
//PostOrder Traversal - Left:Right:rootNode (LRn)
void postOrder(Node node) {
if (node == null)
return;
// first traverse left subtree recursively
postOrder(node.left);
// then traverse right subtree recursively
postOrder(node.right);
// now process root node
System.out.print(node.key + " ");
}
// InOrder Traversal - Left:rootNode:Right (LnR)
void inOrder(Node node) {
if (node == null)
return;
//first traverse left subtree recursively
inOrder(node.left);
//then go for root node
System.out.print(node.key + " ");
//next traverse right subtree recursively
inOrder(node.right);
}
//PreOrder Traversal - rootNode:Left:Right (nLR)
void preOrder(Node node) {
if (node == null)
return;
//first print root node first
System.out.print(node.key + " ");
// then traverse left subtree recursively
preOrder(node.left);
// next traverse right subtree recursively
preOrder(node.right);
}
// Wrappers for recursive functions
void postOrder_traversal() {
postOrder(root); }
void inOrder_traversal() {
inOrder(root); }
void preOrder_traversal() {
preOrder(root); }
}
here i found this codes in stackoverflow, i want te output like this, i can use this but i dont know how can i make this as user input for the data and make it insert the integer into a tree not this manually inserted of the integer. thankyou very much to whoever put effort to understand my question and my situation as newbie.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BTreePrinterTest {
private static Node<Integer> test2() {
Node<Integer> root = new Node<Integer>(2);
Node<Integer> n11 = new Node<Integer>(3);
Node<Integer> n12 = new Node<Integer>(5);
Node<Integer> n21 = new Node<Integer>(2);
Node<Integer> n22 = new Node<Integer>(6);
Node<Integer> n23 = new Node<Integer>(9);
Node<Integer> n31 = new Node<Integer>(5);
root.left = n11;
root.right = n12;
n11.left = n21;
n11.right = n22;
n12.left = n23;
n12.right = n31;
return root;
}
public static void main(String[] args) {
BTreePrinter.printNode(test2());
}
}
class Node<T extends Comparable<?>> {
Node<T> left, right;
T data;
public Node(T data) {
this.data = data;
}
}
class BTreePrinter {
public static <T extends Comparable<?>> void printNode(Node<T> root) {
int maxLevel = BTreePrinter.maxLevel(root);
printNodeInternal(Collections.singletonList(root), 1, maxLevel);
}
private static <T extends Comparable<?>> void printNodeInternal(List<Node<T>> nodes, int level, int maxLevel) {
if (nodes.isEmpty() || BTreePrinter.isAllElementsNull(nodes))
return;
int floor = maxLevel - level;
int endgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0)));
int firstSpaces = (int) Math.pow(2, (floor)) - 1;
int betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1;
BTreePrinter.printWhitespaces(firstSpaces);
List<Node<T>> newNodes = new ArrayList<Node<T>>();
for (Node<T> node : nodes) {
if (node != null) {
System.out.print(node.data);
newNodes.add(node.left);
newNodes.add(node.right);
} else {
newNodes.add(null);
newNodes.add(null);
System.out.print(" ");
}
BTreePrinter.printWhitespaces(betweenSpaces);
}
System.out.println("");
for (int i = 1; i <= endgeLines; i++) {
for (int j = 0; j < nodes.size(); j++) {
BTreePrinter.printWhitespaces(firstSpaces - i);
if (nodes.get(j) == null) {
BTreePrinter.printWhitespaces(endgeLines + endgeLines + i + 1);
continue;
}
if (nodes.get(j).left != null)
System.out.print("/");
else
BTreePrinter.printWhitespaces(1);
BTreePrinter.printWhitespaces(i + i - 1);
if (nodes.get(j).right != null)
System.out.print("\\");
else
BTreePrinter.printWhitespaces(1);
BTreePrinter.printWhitespaces(endgeLines + endgeLines - i);
}
System.out.println("");
}
printNodeInternal(newNodes, level + 1, maxLevel);
}
private static void printWhitespaces(int count) {
for (int i = 0; i < count; i++)
System.out.print(" ");
}
private static <T extends Comparable<?>> int maxLevel(Node<T> node) {
if (node == null)
return 0;
return Math.max(BTreePrinter.maxLevel(node.left), BTreePrinter.maxLevel(node.right)) + 1;
}
private static <T> boolean isAllElementsNull(List<T> list) {
for (Object object : list) {
if (object != null)
return false;
}
return true;
}
}
btw im learning this by my own, i tried merging the two codes but it gives me error i cant fix it.
I should have not made the whole exercise for you, so please try to understand the code. Tell me if something is not clear for you.
public static void main(String[] args) throws IOException {
System.out.println("Write your input");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String lines = br.readLine();
binarySearchTree b = new binarySearchTree();
b.input(lines);
b.print();
}
These functions go to binarySearchTree.
protected void printRecursive(Node node, int depth) {
System.out.println("");
for(int i = 0; i<depth; i++) {
System.out.print(" ");
}
System.out.print(node.key);
if(node.left != null) {
printRecursive(node.left, depth + 1);
}
if(node.right != null) {
printRecursive(node.right, depth + 1);
}
}
public void input(String s) throws IOException {
String[] strs = s.trim().split("\\s+");
for (int i = 0; i < strs.length; i++) {
insert(Integer.parseInt(strs[i]));
}
}
Also i used this answer in my code.
The point of this project is to get an array from the user and use it to create a tree using nodes. The next step is to call a method to check if it represents a Binary Tree. I've been working on this for hours and can't seem to find the correct method to check.
Here is my code so far. I have done everything but the isBinaryTree() method to check if it is a Binary Tree.
import java.util.Scanner;
public class TestBinaryTree
{
Node root;
public void addNode(int key)
{
Node newNode = new Node(key);
if(root == null)
{
root = newNode;
}
else
{
Node focusNode = root;
Node parent;
while(true)
{
parent = focusNode;
if(key < focusNode.key)
{
focusNode = focusNode.leftChild;
if(focusNode == null)
{
parent.leftChild = newNode;
return;
}
}
else
{
focusNode = focusNode.rightChild;
if(focusNode == null)
{
parent.rightChild = newNode;
return;
}
}
}
}
}
/*public static boolean isBinaryTree(int rt, int lft, int rght)
{
}*/
public static void main(String[] args)
{
int Nroot, Nleft, Nright;
Scanner input = new Scanner(System.in);
TestBinaryTree theTree = new TestBinaryTree();
System.out.println("How many numbers are in the array: ");
int num = input.nextInt();
int arr[]=new int[num];
System.out.println("Enter the numbers: ");
for(int i=0;i<num;i++)
{
arr[i] = input.nextInt();
theTree.addNode(arr[i]);
}
}
}
class Node
{
int key;
Node leftChild;
Node rightChild;
Node(int key)
{
this.key = key;
}
public String toString()
{
return "Node: " + key;
}
}
Iterator words = treeSearch.getItems().iterator();
int addCount = 0;
while (words.hasNext())
{
numWords++;
rootNode = add(objectToReference, addCount++, (ITreeSearch) words.next(), 0, rootNode);
}
//Add to the Tree
private TernaryTreeNode add(Object storedObject, int wordNum, ITreeSearch treeSearch, int pos, TernaryTreeNode parentNode) throws NoSearchValueSetException
{
if (parentNode == null)
{
parentNode = new TernaryTreeNode(treeSearch.getNodeValue(pos));
}
if (parentNode.lessThan(treeSearch, pos))
{
parentNode.left = add(storedObject, wordNum, treeSearch, pos, parentNode.left);
}
else if (parentNode.greaterThan(treeSearch, pos))
{
parentNode.right = add(storedObject, wordNum, treeSearch, pos, parentNode.right);
}
else
{
if (pos < treeSearch.getNumberNodeValues())
{
parentNode.mid = add(storedObject, wordNum, treeSearch, pos + 1, parentNode.mid);
}
else
{
numberOfObjectsStored++;
parentNode.addStoredData(storedObject);
}
}
return parentNode;
}
This a snippet of my code in my Ternary Tree which I use for inserting a Name of a person(can hav multiple words in a name, like Michele Adams, Tina Joseph George, etc). I want to convert the above recursion to a for loop / while iterator.
Please guide me on this.
General idea in replacing recursion with iteration is to create a state variable, and update it in the loop by following the same rules that you follow in your recursive program. This means that when you pick a left subtree in the recursive program, you update the state to reference the left subtree; when you go to the right subtree, the state changes to reference the right subtree, and so on.
Here is an example of how to rewrite the classic insertion into binary tree without recursion:
public TreeNode add(TreeNode node, int value) {
// Prepare the node that we will eventually insert
TreeNode insert = new TreeNode();
insert.data = value;
// If the parent is null, insert becomes the new parent
if (node == null) {
return insert;
}
// Use current to traverse the tree to the point of insertion
TreeNode current = node;
// Here, current represents the state
while (true) {
// The conditional below will move the state to the left node
// or to the right node, depending on the current state
if (value < current.data) {
if (current.left == null) {
current.left = insert;
break;
} else {
current = current.left;
}
} else {
if (current.right == null) {
current.right = insert;
break;
} else {
current = current.right;
}
}
}
// This is the original node, not the current state
return node;
}
Demo.
Thanks dasblinkenlight..
This is my logic for replacing the above recursive function for a ternary tree.
Iterator words = treeSearch.getItems().iterator();
while (words.hasNext())
{
for (int i = 0; i < word.getNumberNodeValues(); i++)
{
add_Non_Recursive(objectToReference, word, i);
}
}
//Add to Tree
private void add_Non_Recursive(Object storedObject, ITreeSearch treeSearch, int pos) throws NoSearchValueSetException
{
TernaryTreeNode currentNode = rootNode;
// Start from a node(parentNode). If there is no node, then we create a new node to insert into the tree.
// This could even be the root node.
if (rootNode == null)
{
rootNode = new TernaryTreeNode(treeSearch.getNodeValue(pos));
}
else
{
while (currentNode != null)
{
if (currentNode.lessThan(treeSearch, pos))
{
if (currentNode.left == null)
{
currentNode.left = new TernaryTreeNode(treeSearch.getNodeValue(pos));
currentNode = null;
}
else
{
currentNode = currentNode.left;
}
}
else if (currentNode.greaterThan(treeSearch, pos))
{
if (currentNode.right == null)
{
currentNode.right = new TernaryTreeNode(treeSearch.getNodeValue(pos));
currentNode = null;
}
else
{
currentNode = currentNode.right;
}
}
else
{
if (currentNode.mid == null)
{
currentNode.mid = new TernaryTreeNode(treeSearch.getNodeValue(pos));
currentNode = null;
}
else
{
currentNode = currentNode.mid;
}
}
}
}
}
But I dropped this logic as it wasnt great in performing, it took more time than the recursive counterpart.
I've been coding a basic binary Tree in Java and have run into a problem. The goal of this program is to "learn" new questions in order to guess an animal similar to 20 questions. However, I have no idea how to "save" a node so it can be recalled by this same class the next time it runs. How to do this?
public class LearningTree {
Node root;
public void addNode(double key, String name){
Node newNode = new Node(key, name);
if (root == null){
root = newNode;
} else {
Node focusNode = root;
Node parent;
while(true){
parent = focusNode;`enter code here`
if(key < focusNode.key){
focusNode = focusNode.leftChild;
if(focusNode == null){
parent.leftChild = newNode;
return;
}
} else {
focusNode = focusNode.rightChild;
if(focusNode == null){
parent.rightChild = newNode;
return;
}
}
}
}
}
public void traverse(Node focusNode){
if(focusNode != null){
traverse(focusNode.leftChild);
traverse(focusNode.rightChild);
}
}
class Node{
double key;
String name;
Node leftChild;
Node rightChild;
Node(double key, String name){
this.key = key;
this.name = name;
}
}
public void keyChange(Node focusNode, double newkey){
focusNode.key = newkey;
}
public Node findNode(double 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 static void main(String[] args){
LearningTree Tree = new LearningTree();
Scanner sc = new Scanner(System.in);
//Nodes
Tree.addNode(1500, "Does it have wings?");
Tree.addNode(750, "Is it a dog?");
System.out.println("Is it an animal?");
double n = 1000;
while(true){
String Answer = sc.nextLine();
String answer = Answer.toLowerCase();
double k = n;
if(answer.equals("y")){
n = 1.5* n;
}
if(answer.equals("n")){
n = .5*n;
}
if(Tree.findNode(n) != null){
System.out.println(Tree.findNode(n).name + " (y/n)");
}
if(Tree.findNode(n) == null){
System.out.println("What is it?");
String answer1 = sc.nextLine();
System.out.println("What would distinguish a " + answer1 + "from the previous guess?");
String answer2 = sc.nextLine();
System.out.println("What would the answer be to " + answer2 + "? (y/n)");
String answer3 = sc.nextLine();
double s;
if(Tree.findNode(k/1.5) == null){
Tree.findNode(k/.5);
} else {
Tree.findNode(k/1.5);
}
if(answer3.equals("y")){
Tree.keyChange(Tree.findNode(k), n );
s = 1.5;
Tree.addNode(n, Tree.findNode(n).name);
}
if(answer3.equals("n")){
Tree.keyChange(Tree.findNode(k), n);
s = .5;
Tree.addNode(n, Tree.findNode(n).name );
}
Tree.addNode(k, answer2);
}
}
}
}
Maybe you could use a local file and serialize the data. Java handles this pretty well.
NOTE: I haven't tested this code but it's a starting place.
private void saveNode(Node n){
FileOutputStream fout = new FileOutputStream("file.txt");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(n);
oos.close();
}
private Node readNode(){
FileInputStream fin = new FileInputStream("file.txt");
ObjectInputStream ois = new ObjectInputStream(fin);
Node n = (Node)ois.readObject();
ois.close();
return n;
}
You might want to serialize this object to a file so that it can get the data back when it runs next time through deserialize. Check ObjectOutputstream class's documentation. Having said that you need to have some logic to go with it,