I am going over my old test from Data Structures, and I cannot figure out how to implement the printtree(int level) method in my Tree class. I am restricted to using this structure. I cannot figure out an implementation to use without root.right or root.left, this is very frustrating.
/*
Exam 2. Problem 2. 03/09/2012
*/
import java.util.List;
import java.util.ArrayList;
/**
A tree in which each node has an arbitrary number of children.
*/
public class Tree
{
private Node root;
class Node
{
public Object data;
public List<Node> children;
/**
Computes the size of the subtree whose root is this node.
#return the number of nodes in the subtree
*/
public int size()
{
int sum = 0;
for (Node child : children) { sum = sum + child.size(); }
return 1 + sum;
}
public int leaves() {
int count = 0;
for (Node child : children) {
if (child.size() == 1) {
count = count + 1;
} else {
count = count + child.leaves();
}
}
if (count == 0) {
count = count + 1;
}
return count;
}
public String printTree(int level) {
String S = "";
S += root.data + " (level:" + level + ") ";
if (root != null) {
return S;
}
if (root.children != null) {
S += root.printTree(level + 1);
}
return S;
}
}
/**
Constructs an empty tree.
*/
public Tree()
{
root = null;
}
/**
Constructs a tree with one node and no children.
#param rootData the data for the root
*/
public Tree(Object rootData)
{
root = new Node();
root.data = rootData;
root.children = new ArrayList<Node>();
}
/**
Adds a subtree as the last child of the root.
*/
public void addSubtree(Tree subtree)
{
root.children.add(subtree.root);
}
/**
Computes the size of this tree.
#return the number of nodes in the tree
*/
public int size()
{
if (root == null) { return 0; }
else { return root.size(); }
}
public int leaves() {
Node newNode = root;
if (root == null) { return 0; }
else { return root.leaves(); }
}
public String printTree() {
return root.children.printTree(0);
}
}
you just need to change 3 things:
Change root to this every where in the printTree(int level) method
The placement of if(this == null) should be checked before anything else
Use a for loop to print all of the children
public String printTree(int level) {
String S = "";
// notice the change to '=='
if (this == null)
return S;
S += this.data + " (level:" + level + ") ";
// notice the for loop
if( this.children != null)
for(Node child : this.children)
S += child.printTree(level + 1);
return S;
}
Related
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.
I have a project which is to “Start with the tree.java program (Listing 8.1) and modify it to create a binary
tree from a string of letters (like A, B, and so on) entered by the user. Each
letter will be displayed in its own node. Construct the tree so that all the nodes
that contain letters are leaves. Parent nodes can contain some non-letter
symbol like +. Make sure that every parent node has exactly two children.
Don’t worry if the tree is unbalanced.” The book gives us a hint on how to begin. “One way to begin is by making an array of trees. (A group of unconnected trees
is called a forest.) Take each letter typed by the user and put it in a node. Take
each of these nodes and put it in a tree, where it will be the root. Now put all
these one-node trees in the array. Start by making a new tree with + at the root
and two of the one-node trees as its children. Then keep adding one-node trees
from the array to this larger tree. Don’t worry if it’s an unbalanced tree.”
import java.io.*;
import java.util.*;
class Node
{
public String iData; // data item (key)
public Node leftChild; // this node’s left child
public Node rightChild; // this node’s right child
public void displayNode() // display ourself
{
System.out.print('{');
System.out.print(iData);
System.out.print("} ");
}
} // end class Node
class Tree
{
private Node root; // first node of tree
public void setNode(Node newNode)
{root = newNode;}
public Node getNode()
{return root;}
// -------------------------------------------------------------
public Tree() // constructor
{ root = null; } // no nodes in tree yet
// -------------------------------------------------------------
public void traverse(int traverseType)
{
switch(traverseType)
{
case 1: System.out.print("nPreorder traversal: ");
preOrder(root);
break;
case 2: System.out.print("nInorder traversal: ");
inOrder(root);
break;
case 3: System.out.print("nPostorder traversal: ");
postOrder(root);
break;
}
System.out.println();
}
private void preOrder(Node localRoot)
{
if(localRoot != null)
{
System.out.print(localRoot.iData + " ");
preOrder(localRoot.leftChild);
preOrder(localRoot.rightChild);
}
}
// -------------------------------------------------------------
private void inOrder(Node localRoot)
{
if(localRoot != null)
{
inOrder(localRoot.leftChild);
System.out.print(localRoot.iData + " ");
inOrder(localRoot.rightChild);
}
}
// -------------------------------------------------------------
private void postOrder(Node localRoot)
{
if(localRoot != null)
{
postOrder(localRoot.leftChild);
postOrder(localRoot.rightChild);
System.out.print(localRoot.iData + " ");
}
}
// -------------------------------------------------------------
public void displayTree()
{
Stack globalStack = new Stack();
globalStack.push(root);
int nBlanks = 32;
boolean isRowEmpty = false;
System.out.println(
"......................................................");
while(isRowEmpty==false)
{
Stack localStack = new Stack();
isRowEmpty = true;
for(int j=0; j<nBlanks; j++)
System.out.print(' ');
while(globalStack.isEmpty()==false)
{
Node temp = (Node)globalStack.pop();
if(temp != null)
{
System.out.print(temp.iData);
localStack.push(temp.leftChild);
localStack.push(temp.rightChild);
if(temp.leftChild != null ||
temp.rightChild != null)
isRowEmpty = false;
}
else
{
System.out.print("--");
localStack.push(null);
localStack.push(null);
}
for(int j=0; j<nBlanks*2-2; j++)
System.out.print(' ');
} // end while globalStack not empty
System.out.println();
nBlanks /= 2;
while(localStack.isEmpty()==false)
globalStack.push( localStack.pop() );
} // end while isRowEmpty is false
System.out.println(
"......................................................");
} // end displayTree()
// -------------------------------------------------------------
}
public class Leaves
{
//function used to enter the single node trees into a larger tree
public static void enterLetters(Node localRoot, Tree[] nodeTree, int i)
{
if(localRoot != null && i == nodeTree.length)
{
if(nodeTree.length == i - 1)
{
localRoot.leftChild = nodeTree[i].getNode();
localRoot.rightChild = nodeTree[i + 1].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
}
else
{
Node plusNode = new Node();
plusNode.iData = "+";
localRoot.leftChild = plusNode;
localRoot.rightChild = nodeTree[i].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
}
}
}
public static void main(String[] args)
{
Tree[] forest = new Tree[10];
Scanner sc = new Scanner(System.in);
for(int i = 0; i < 10; i++)
{
String letter;
forest[i] = new Tree();
System.out.println("Enter a letter: ");
letter = sc.nextLine();
Node newNode = new Node();
newNode.iData = letter;
forest[i].setNode(newNode);
}
Tree letterTree = new Tree();
Node firstNode = new Node();
firstNode.iData = "+";
letterTree.setNode(firstNode);
enterLetters(letterTree.getNode(), forest, 0);
letterTree.displayTree();
}
}
My problem is trying to get the array of single node trees into the larger tree. I tried making a recursive function but when I display the larger tree it only shows the first node and it is as if the function enterLeaves never did it’s job.
This can't be correct:
public static void enterLetters(Node localRoot, Tree[] nodeTree, int i) {
if (localRoot != null && i == nodeTree.length) {
if (nodeTree.length == i - 1) {
localRoot.leftChild = nodeTree[i].getNode();
localRoot.rightChild = nodeTree[i + 1].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
} else {
Node plusNode = new Node();
plusNode.iData = "+";
localRoot.leftChild = plusNode;
localRoot.rightChild = nodeTree[i].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
}
}
}
When you enter this method: localRoot != null, i == 0, and nodeTree.length==10
So the if statement is failing. I am guess the if statement should read:
if (localRoot != null && i < nodeTree.length)
Also, I am pretty sure your second if statement is incorrect also; I believe it should be.
if (nodeTree.length-2 == i) {
localRoot.leftChild = nodeTree[i].getNode();
localRoot.rightChild = nodeTree[i + 1].getNode();
return;
}
Instead of:
if (nodeTree.length == i - 1) {
localRoot.leftChild = nodeTree[i].getNode();
localRoot.rightChild = nodeTree[i + 1].getNode();
enterLetters(localRoot.leftChild, nodeTree, i + 1);
}
You want to stop when you have two Nodes left to process (nodeTree.length-2 == i) and after you do that you should return instead of entering the remaining letters.
Here's what I came up with that works:
Node.java
/** Represents a node in a binary tree data structure */
public class Node {
private char letter;
private Node leftChild;
private Node rightChild;
public Node(char letter) {
this.letter = letter;
}
public void setRightChild(Node rightChild) {
this.rightChild = rightChild;
}
public Node getRightChild() {
return rightChild;
}
public void setLeftChild(Node leftChild) {
this.leftChild = leftChild;
}
public Node getLeftChild() {
return leftChild;
}
/** Returns a String representation of this node. */
#Override
public String toString() {
return "" + letter;
}
}
Tree.java
import java.util.Stack;
/**
* A binary tree
*/
public class Tree {
private Node root;
public void setRoot(Node root) {
this.root = root;
}
public void addToLeft(Node node) {
root.setLeftChild(node);
}
public void addToRight(Node node) {
root.setRightChild(node);
}
public Node getRoot() {
return root;
}
public void displayTree() {
Stack<Node> globalStack = new Stack<>();
globalStack.push(root);
int nBlanks = 32;
boolean isRowEmpty = false;
System.out.println(
"......................................................");
while (!isRowEmpty) {
Stack<Node> localStack = new Stack<>();
isRowEmpty = true;
for (int j = 0; j < nBlanks; j++)
System.out.print(' ');
while (!globalStack.isEmpty()) {
Node temp = (Node) globalStack.pop();
if (temp != null) {
System.out.print(temp);
localStack.push(temp.getLeftChild());
localStack.push(temp.getRightChild());
if (temp.getLeftChild() != null ||
temp.getRightChild() != null)
isRowEmpty = false;
} else {
System.out.print("--");
localStack.push(null);
localStack.push(null);
}
for (int j = 0; j < nBlanks * 2 - 2; j++)
System.out.print(' ');
} // end while globalStack not empty
System.out.println();
nBlanks /= 2;
while (!localStack.isEmpty())
globalStack.push(localStack.pop());
} // end while isRowEmpty is false
System.out.println(
"......................................................");
}
}
Forest.java
/**
* A collection of OneNodeTrees combined together in one tree
*/
public class Forest {
private Tree[] forest;
private int forestIndex;
public Forest(int numTrees) {
forest = new Tree[numTrees];
forestIndex = 0;
}
public boolean add(Tree tree) {
if(forestIndex < forest.length) {
forest[forestIndex++] = tree;
return true;
} else {
return false;
}
}
public Tree createMainTree() {
Tree firstTree = new Tree();
firstTree.setRoot(new Node('+'));
firstTree.addToLeft(forest[0].getRoot());
firstTree.addToRight(forest[1].getRoot());
forest[1] = firstTree;
int mainTreeIndex = 0;
Tree tempTree;
for(mainTreeIndex = 2; mainTreeIndex < forest.length; mainTreeIndex++) {
tempTree = new Tree();
tempTree.setRoot(new Node('+'));
tempTree.addToLeft(forest[mainTreeIndex - 1].getRoot());
tempTree.addToRight(forest[mainTreeIndex].getRoot());
forest[mainTreeIndex] = tempTree;
}
return forest[mainTreeIndex - 1];
}
public static void main(String[] args) {
final int numberOfTrees = 6;
Forest forest = new Forest(numberOfTrees);
// Add characters starting from A which has ASCII value 65
int charLimit = 65 + numberOfTrees;
for(int i = 65; i < charLimit; i++) {
// Make new node.
Node newNode = new Node((char) i);
// Add that node to Tree as a root.
Tree newTree = new Tree();
newTree.setRoot(newNode);
// And add that one-node tree to forest(array)
forest.add(newTree);
}
Tree mainTree = forest.createMainTree();
mainTree.displayTree();
}
}
if(localRoot != null && i == nodeTree.length -1)
if you do not subtract one from node tree length you will have a duplicate child under the final parent node with 2 children
I have constructed a binary search tree using a text file that is read in by the main function. The resulting tree contains the words of the text file, with a count so that the same word is not inserted twice. The problem is not with constructing the tree, but getting the information to display properly. The data is required to be printed out in columns of 4, as to keep it readable.
Example:
|BTNode1|BTNode2|BTNode3|BTNode4|
|BTNode5|BTNode6|BTNode7|BTNode8|
The BTNode class has a toString() method that prints out the data of the individual nodes. But, whenever I call this code below with the root node, and a count of 0 I get the node information properly, but in weird numbers of nodes per column. Any ideas how to get this to work? I can post additional code if necessary.
EDIT: Added entire class to reflect changes, and added sample current output. Might be a problem with constructing the tree.
EDIT2: Changed printcount = 1, fixes the display problems. Code now works properly.
package speech;
public class BSTree {
private BTNode root;
private final String DISPLAY_FORMAT_CAPS =
"*****************************************************************";
private StringBuilder buffer = new StringBuilder();
private int printcount = 1;
public BSTree (){
root = null;
}
public BTNode insert(String indata, boolean lowercase){
if(lowercase){
if(root != null){
return insertRecursive(root,indata.toLowerCase());
}
else{
root = new BTNode(indata.toLowerCase());
return root;
}
}
else{
if(root != null){
return insertRecursive(root,indata);
}
else{
root = new BTNode(indata);
return root;
}
}
}
private BTNode insertRecursive(BTNode node, String value) {
if (value.compareTo(node.data) < 0){
if (node.left != null) {
return insertRecursive(node.left, value);
} else {
//System.out.println(" Inserted " + value + " to left of Node " + node.data);
node.left = new BTNode(value);
return node.left;
}
} else if (value.compareTo(node.data) > 0) {
if (node.right != null) {
return insertRecursive(node.right, value);
} else {
//System.out.println(" Inserted " + value + " to right of Node " + node.data);
node.right = new BTNode(value);
return node.left;
}
} else if (value.compareTo(node.data) == 0){
node.incrementCount();
//System.out.println("Incremented count of " + value + " to: " + node.wordcount);
return node;
}
return null;
}
private int wordcountRecursive(BTNode node){
if(node == null){
return 0;
}
else{
return wordcountRecursive(node.left) + node.wordcount + wordcountRecursive(node.right);
}
}
public int wordcount(){
return wordcountRecursive(root);
}
public void display(){
System.out.println(DISPLAY_FORMAT_CAPS);
displayRecursive(root);
System.out.println(buffer.toString());
System.out.println(DISPLAY_FORMAT_CAPS);
System.out.println("Word Count:" + wordcount());
}
private void displayRecursive (BTNode node){
//System.out.println(count);
if(node != null){
displayRecursive(node.left);
addNodeDisplay(node);
displayRecursive(node.right);
}
}
private void addNodeDisplay(BTNode node){
if(printcount % 4 != 0){
buffer.append("|").append(node);
}
else{
buffer.append("|").append(node).append("|\n");
}
printcount++;
}
}
I've added some sample data and this looks like it works:
private void displayRecursive(Node node) {
displayRecursive(node, 0);
System.out.println("");
}
private int displayRecursive(Node node, int count) {
if (node != null) {
// Do left first.
count = displayRecursive(node.getLeft(), count);
// New line?
if (count > 0 && count % 4 == 0) {
// End of line.
System.out.println("|");
}
// Then me.
System.out.print("|" + node);
count += 1;
// Then right.
count = displayRecursive(node.getRight(), count);
}
return count;
}
private void test() {
Node root = new Node("Root");
Node left = new Node("Left");
Node right = new Node("Right");
root.setLeft(left);
root.setRight(right);
Node leftLeft = new Node("Left.Left");
leftLeft.setLeft(new Node("LeftLeftLeft"));
leftLeft.setRight(new Node("LeftLeftRight"));
left.setLeft(leftLeft);
left.setRight(new Node("Left.Right"));
right.setLeft(new Node("Right.Left"));
right.setRight(new Node("Right.Right"));
displayRecursive(root);
}
public static void main(String[] args) throws InterruptedException {
try {
Test test = new Test();
test.test();
} catch (Exception e) {
e.printStackTrace();
}
}
static class Node {
final String data;
private Node left = null;
private Node right = null;
Node(String data) {
this.data = data;
}
#Override
public String toString() {
return data;
}
/**
* #return the left
*/
public Node getLeft() {
return left;
}
/**
* #param left the left to set
*/
public void setLeft(Node left) {
this.left = left;
}
/**
* #return the right
*/
public Node getRight() {
return right;
}
/**
* #param right the right to set
*/
public void setRight(Node right) {
this.right = right;
}
}
it prints:
|LeftLeftLeft|Left.Left|LeftLeftRight|Left|
|Left.Right|Root|Right.Left|Right|
|Right.Right
This is what I have. I thought pre-order was the same and mixed it up with depth first!
import java.util.LinkedList;
import java.util.Queue;
public class Exercise25_1 {
public static void main(String[] args) {
BinaryTree tree = new BinaryTree(new Integer[] {10, 5, 15, 12, 4, 8 });
System.out.print("\nInorder: ");
tree.inorder();
System.out.print("\nPreorder: ");
tree.preorder();
System.out.print("\nPostorder: ");
tree.postorder();
//call the breadth method to test it
System.out.print("\nBreadthFirst:");
tree.breadth();
}
}
class BinaryTree {
private TreeNode root;
/** Create a default binary tree */
public BinaryTree() {
}
/** Create a binary tree from an array of objects */
public BinaryTree(Object[] objects) {
for (int i = 0; i < objects.length; i++) {
insert(objects[i]);
}
}
/** Search element o in this binary tree */
public boolean search(Object o) {
return search(o, root);
}
public boolean search(Object o, TreeNode root) {
if (root == null) {
return false;
}
if (root.element.equals(o)) {
return true;
}
else {
return search(o, root.left) || search(o, root.right);
}
}
/** Return the number of nodes in this binary tree */
public int size() {
return size(root);
}
public int size(TreeNode root) {
if (root == null) {
return 0;
}
else {
return 1 + size(root.left) + size(root.right);
}
}
/** Return the depth of this binary tree. Depth is the
* number of the nodes in the longest path of the tree */
public int depth() {
return depth(root);
}
public int depth(TreeNode root) {
if (root == null) {
return 0;
}
else {
return 1 + Math.max(depth(root.left), depth(root.right));
}
}
/** Insert element o into the binary tree
* Return true if the element is inserted successfully */
public boolean insert(Object o) {
if (root == null) {
root = new TreeNode(o); // Create a new root
}
else {
// Locate the parent node
TreeNode parent = null;
TreeNode current = root;
while (current != null) {
if (((Comparable)o).compareTo(current.element) < 0) {
parent = current;
current = current.left;
}
else if (((Comparable)o).compareTo(current.element) > 0) {
parent = current;
current = current.right;
}
else {
return false; // Duplicate node not inserted
}
}
// Create the new node and attach it to the parent node
if (((Comparable)o).compareTo(parent.element) < 0) {
parent.left = new TreeNode(o);
}
else {
parent.right = new TreeNode(o);
}
}
return true; // Element inserted
}
public void breadth() {
breadth(root);
}
// Implement this method to produce a breadth first
// search traversal
public void breadth(TreeNode root){
if (root == null)
return;
System.out.print(root.element + " ");
breadth(root.left);
breadth(root.right);
}
/** Inorder traversal */
public void inorder() {
inorder(root);
}
/** Inorder traversal from a subtree */
private void inorder(TreeNode root) {
if (root == null) {
return;
}
inorder(root.left);
System.out.print(root.element + " ");
inorder(root.right);
}
/** Postorder traversal */
public void postorder() {
postorder(root);
}
/** Postorder traversal from a subtree */
private void postorder(TreeNode root) {
if (root == null) {
return;
}
postorder(root.left);
postorder(root.right);
System.out.print(root.element + " ");
}
/** Preorder traversal */
public void preorder() {
preorder(root);
}
/** Preorder traversal from a subtree */
private void preorder(TreeNode root) {
if (root == null) {
return;
}
System.out.print(root.element + " ");
preorder(root.left);
preorder(root.right);
}
/** Inner class tree node */
private class TreeNode {
Object element;
TreeNode left;
TreeNode right;
public TreeNode(Object o) {
element = o;
}
}
}
Breadth first search
Queue<TreeNode> queue = new LinkedList<BinaryTree.TreeNode>() ;
public void breadth(TreeNode root) {
if (root == null)
return;
queue.clear();
queue.add(root);
while(!queue.isEmpty()){
TreeNode node = queue.remove();
System.out.print(node.element + " ");
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
}
Breadth first is a queue, depth first is a stack.
For breadth first, add all children to the queue, then pull the head and do a breadth first search on it, using the same queue.
For depth first, add all children to the stack, then pop and do a depth first on that node, using the same stack.
It doesn't seem like you're asking for an implementation, so I'll try to explain the process.
Use a Queue. Add the root node to the Queue. Have a loop run until the queue is empty. Inside the loop dequeue the first element and print it out. Then add all its children to the back of the queue (usually going from left to right).
When the queue is empty every element should have been printed out.
Also, there is a good explanation of breadth first search on wikipedia: http://en.wikipedia.org/wiki/Breadth-first_search
public void breadthFirstSearch(Node root, Consumer<String> c) {
List<Node> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
Node n = queue.remove(0);
c.accept(n.value);
if (n.left != null)
queue.add(n.left);
if (n.right != null)
queue.add(n.right);
}
}
And the Node:
public static class Node {
String value;
Node left;
Node right;
public Node(final String value, final Node left, final Node right) {
this.value = value;
this.left = left;
this.right = right;
}
}
//traverse
public void traverse()
{
if(node == null)
System.out.println("Empty tree");
else
{
Queue<Node> q= new LinkedList<Node>();
q.add(node);
while(q.peek() != null)
{
Node temp = q.remove();
System.out.println(temp.getData());
if(temp.left != null)
q.add(temp.left);
if(temp.right != null)
q.add(temp.right);
}
}
}
}
This code which you have written, is not producing correct BFS traversal:
(This is the code you claimed is BFS, but in fact this is DFS!)
// search traversal
public void breadth(TreeNode root){
if (root == null)
return;
System.out.print(root.element + " ");
breadth(root.left);
breadth(root.right);
}
For implementing the breadth first search, you should use a queue. You should push the children of a node to the queue (left then right) and then visit the node (print data). Then, yo should remove the node from the queue. You should continue this process till the queue becomes empty. You can see my implementation of the BFS here: https://github.com/m-vahidalizadeh/foundations/blob/master/src/algorithms/TreeTraverse.java
Use the following algorithm to traverse in breadth first search-
First add the root node into the queue with the put method.
Iterate while the queue is not empty.
Get the first node in the queue, and then print its value.
Add both left and right children into the queue (if the current
nodehas children).
Done. We will print the value of each node, level by level,by
poping/removing the element
Code is written below-
Queue<TreeNode> queue= new LinkedList<>();
private void breadthWiseTraversal(TreeNode root) {
if(root==null){
return;
}
TreeNode temp = root;
queue.clear();
((LinkedList<TreeNode>) queue).add(temp);
while(!queue.isEmpty()){
TreeNode ref= queue.remove();
System.out.print(ref.data+" ");
if(ref.left!=null) {
((LinkedList<TreeNode>) queue).add(ref.left);
}
if(ref.right!=null) {
((LinkedList<TreeNode>) queue).add(ref.right);
}
}
}
The following is a simple BFS implementation for BinaryTree with java 8 syntax.
void bfsTraverse(Node node, Queue<Node> tq) {
if (node == null) {
return;
}
System.out.print(" " + node.value);
Optional.ofNullable(node.left).ifPresent(tq::add);
Optional.ofNullable(node.right).ifPresent(tq::add);
bfsTraverse(tq.poll(), tq);
}
Then invoke this with root node and a Java Queue implementation
bfsTraverse(root, new LinkedList<>());
Even better if it is regular tree, could use following line instead as there is not only left and right nodes.
Optional.ofNullable(node.getChildern()).ifPresent(tq::addAll);
public static boolean BFS(ListNode n, int x){
if(n==null){
return false;
}
Queue<ListNode<Integer>> q = new Queue<ListNode<Integer>>();
ListNode<Integer> tmp = new ListNode<Integer>();
q.enqueue(n);
tmp = q.dequeue();
if(tmp.val == x){
return true;
}
while(tmp != null){
for(ListNode<Integer> child: n.getChildren()){
if(child.val == x){
return true;
}
q.enqueue(child);
}
tmp = q.dequeue();
}
return false;
}
Im writing a basic AVL tree that holds Objects, im having a Stackoverflow error (lol) in my code to recurse through the tree to get the height of the current node. I dont think my height code is actually the problem so much that my rotation causes my height code to have the problem.
So what I do is I recurse through the children of the node until I reach a null node which returns 0, the next/preceding call (depending on how you look at it) returns the maximum of the return the call on that node + 1 vs whatever the call on the other child ends up being. It should be pretty clear how it works when you see it.
the rotation creates a temporary node from the appropriate child and alters the node and sets it to the child of the temporary node and sets the parent values to the proper nodes. (Each node has a reference not only to a left and right node but the parent node)
The insertion method works fine as far as I can tell, I do have a problem with an infinite loop in my delete method but thats another question for another time.
Hopefully I have given enough info, let me know if there is anything I can clarify this is my first post here. but any help is appreciated, this one even has my instructor stumped.
Thanks for even taking the time to read this wall of text.
import java.lang.Math;
/**
This is an AVL binary search tree class it uses a AVLNode to create an AVL Binary search tree.
*/
public class AVLTree {
AVLNode root;
Index empty;
public AVLTree(){
root = null;
}
public void insert(Object o, String ssNumber){
if (root == null){
root = new AVLNode(o);
System.out.print("adding root");
}
else{
AVLNode current = root;
AVLNode node = new AVLNode(o);
while (current != null){
if (((Comparable)current.getData()).compareTo(ssNumber) < 0){
if (current.getRight() != null){
current = current.getRight();
}
else{
// System.out.println(((Index)(current.getData())).getSocial() + " CURRENT DATA");
current.setRight(node);
current.getRight().setParent(current);
// System.out.println("adding " + ((Index)o).getSocial() + "to the right of" + ((Index)(current.getData())).getSocial());
balanceTree(current);
// if (current.getParent() != null)
// System.out.println("the right child of " + (((Index)(current.getParent().getData())).getSocial()) + " is now " + (((Index)((current.getRight()).getData())).getSocial()) );
current=null;
}
}
else if (((Comparable)current.getData()).compareTo(ssNumber) > 0) {
if (current.getLeft()!= null){
current = current.getLeft();
}
else{
// System.out.println(((Index)(current.getData())).getSocial() + " CURRENT DATA");
current.setLeft(node);
current.getLeft().setParent(current);
// System.out.println("adding " + ((Index)o).getSocial() + "to the left of" + ((Index)(current.getData())).getSocial());
balanceTree(current);
// if (current.getParent() != null)
// System.out.println("the left child of " + (((Index)(current.getParent().getData())).getSocial()) + " is now " + (((Index)((current.getLeft()).getData())).getSocial()) );
current=null;
}
}
}
}
}
public boolean delete(String ssNumber){
AVLNode current = root;
AVLNode parent = null;
while (current.getData() != null){
if (((Comparable)current.getData()).compareTo(ssNumber) > 0){
if(current.getLeft() != null){
parent = current;
current = current.getLeft();
}
else{
//System.out.print(((Index)(current.getData())).getSocial() + "not found");
return false;
}
}
else if (((Comparable)current.getData()).compareTo(ssNumber) < 0){
if (current.getRight()!=null){
parent = current;
current = current.getRight();
}
else{
//System.out.print(((Index)(current.getData())).getSocial() + "not found");
return false;
}
}
else{
if (current.getLeft() != null && current.getRight() != null){
AVLNode leftHighest = null;
AVLNode temp = current.getLeft();
while (temp.getRight() != null){
temp = temp.getRight();
}
leftHighest.setData(temp.getData());
temp.setData(current.getData());
current.setData(leftHighest.getData());
return delete(ssNumber);
}
if (current.getLeft() == null && current.getRight() != null){
if (parent == null){
root = current.getRight();
}
if (current == parent.getLeft()){
parent.setLeft(current.getRight());
}
else{
parent.setRight(current.getRight());
}
}
else if (current.getRight() == null && current.getLeft() != null){
if (parent == null){
root = current.getLeft();
}
if (current == parent.getLeft()){
parent.setLeft(current.getLeft());
}
else{
parent.setRight(current.getLeft());
}
}
else{
current.setData(null);
return true;
}
}
}
//System.out.print(((Index)(current.getData())).getSocial() + "not found");
return false;
}
public int find(String ssNumber){
AVLNode current = root;
while (current.getData() != null){
if (((Comparable)current.getData()).compareTo(ssNumber) > 0){
if(current.getLeft() != null){
current = current.getLeft();
}
else{
//System.out.print(((Index)(current.getData())).getSocial() + "not found");
return -1;
}
}
else if (((Comparable)current.getData()).compareTo(ssNumber) < 0){
if (current.getRight()!=null){
current = current.getRight();
}
else{
//System.out.print(((Index)(current.getData())).getSocial() + "not found");
return -1;
}
}
else{
return ((Index)(current.getData())).getArrayIndex();
}
}
return -1;
}
public void clear(){
root = null;
}
//gets the height of the node's subtrees. Uses recursion to find the max height returns the highest value of each traversal adding 1 for each step.
private int getHeight(AVLNode node){
if (node == null){
return 0;
}
else
{
//int x = getHeight( node.getLeft() );
//int y = getHeight( node.getRight() );
//return Math.max( x, y ) + 1;
return Math.max(getHeight(node.getLeft()), getHeight(node.getRight())) + 1;
}
}
//uses the value of getBalance to decide which type of rotation to undergo, and rotates the node by creating a temporary node from the proper child based on the type value.
//the type value will be passed the balance.
private AVLNode rotateNodes(AVLNode node, int type){
AVLNode temp;
//System.out.println("step C");
if (type == -2){
temp = node.getRight();
temp.setParent(node.getParent());
if (node.getParent() != null){
if (node == node.getParent().getLeft()){
temp.getParent().setLeft(temp);
}
else{
temp.getParent().setRight(temp);
}
}
node.setRight(temp.getLeft());
if (node.getRight() != null){
node.getRight().setParent(node);
}
temp.setLeft(node);
return temp;
}
else if (type == 2){
temp = node.getLeft();
temp.setParent(node.getParent());
if (node.getParent() != null){
if (node == node.getParent().getLeft()){
temp.getParent().setLeft(temp);
}
else{
temp.getParent().setRight(temp);
}
}
node.setLeft(temp.getRight());
if (node.getLeft() != null){
node.getLeft().setParent(node);
}
temp.setRight(node);
node.setParent(temp);
return temp;
}
else
return node;
}
// Runs the methods necessary to balance a tree on each node until it reaches the root.
private void balanceTree(AVLNode node){
AVLNode temp;
while (node != null){
int balance = getHeight(node.getLeft()) - getHeight(node.getRight());
if (balance == 2 || balance == -2){
//System.out.println("step a");
temp = rotateNodes(node, balance);
//System.out.println("rotated");
node.setData(temp.getData());
node.setLeft(temp.getLeft());
node.setRight(temp.getRight());
node.setParent(temp.getParent());
}
else {
//System.out.println("moving on");
node = node.getParent();
}
}
}
//check balance
}
/**
This is an AVL node in a AVL binary tree it contains data and references to its two possible children and it's parent.
*/
public class AVLNode {
private Object data;
private AVLNode left;
private AVLNode right;
private AVLNode parent;
public AVLNode(Object o){
data = o;
left = null;
right = null;
parent = null;
}
public AVLNode(){
data = null;
left = null;
right = null;
parent = null;
}
public Object getData(){
return data;
}
public AVLNode getLeft(){
return left;
}
public AVLNode getRight(){
return right;
}
public void setData(Object index){
data = index;
}
public void setLeft(AVLNode node){
left = node;
}
public void setRight(AVLNode node){
right = node;
}
public void setParent(AVLNode node){
parent = node;
}
public AVLNode getParent(){
return parent;
}
}
/**
The is a person class it holds 6 data fields about a person
*/
public class Person {
private String lastName;
private String firstName;
private String socialSec;
private String phoneNum;
private char gender;
private String date;
public Person(String lastName, String firstName, String socialSec, String phoneNum, char gender, String date) {
this.lastName = lastName;
this.firstName = firstName;
this.socialSec = socialSec;
this.phoneNum = phoneNum;
this.gender = gender;
this.date = date;
}
public String getLast(){
return lastName;
}
public String getFirst(){
return firstName;
}
public String getSocial(){
return socialSec;
}
public void setSocial(String string){
this.socialSec = string;
}
public String getPhone(){
return phoneNum;
}
public char getGender(){
return gender;
}
public String getDate(){
return date;
}
public String toString(){
return ("Lastname: " + lastName + "\nFirstname: " + firstName + "\nSocial Security " + socialSec +
"\nPhone Number: " + phoneNum + "\ngender " + gender);
}
}
/**
This is an index object it will contain the data type used as reference the binary tree, the social, and the references location in the array
*/
public class Index implements Comparable {
String social;
int arrayIndex;
public Index(String social, int arrayIndex) {
this.social = social;
this.arrayIndex = arrayIndex;
}
public String getSocial(){
return social;
}
public void setSocial(String social){
this.social = social;
}
public int getArrayIndex(){
return arrayIndex;
}
public void setArrayIndex(int arrayIndex){
this.arrayIndex = arrayIndex;
}
public int compareTo(Object o){
return social.compareTo((String)o);
}
}
Here is the data read in from datafile (this is fake info)
Hattell Zara 568472178 9562266952 F 8/23/1985
Poff Naomi 070028388 1868991633 F 10/25/1967
Jackson Finley 766879776 6317272316 M 8/28/1984
Lark Kasey 278473635 4953108522 F 9/19/1967
Grifith Josh 223948515 5916186412 M 11/21/1964
Grimsby Mitchel 057848901 4921537476 M 10/28/1969
Heesicker Samara 578308596 0089823308 F 7/27/1964
Amos Kasey 148842321 7949241129 F 2/10/1985
Johnson Angeline 003513447 8828061677 F 4/21/1977
Aldridge John 418953690 5006720120 M 6/23/1968
Mckibbon Vasilios 523212165 0040010068 M 7/30/1972
Woodhouse Jacob 522626205 6985940430 M 7/31/1966
Newell Shante 022753752 8483983762 F 2/24/1978
Ramer Tyler 025694346 6123635287 M 9/14/1980
Leatherman Tige 297071697 1106435680 M 8/11/1981
Johnston Halle 263543220 3417907710 F 11/17/1960
Aber Myah 669617355 3276358736 F 12/10/1961
Frizzle Archie 150388947 1472418810 M 8/5/1960
Mcdivit Ashley 294735567 2017661755 M 11/3/1978
Jackson Sophie 698928462 0185800213 F 3/18/1960
Bechtel William 700321659 1376473348 M 11/30/1974
Larimer Alessi 745219302 2445633750 F 12/12/1964
Bodler Amelie 424759320 2676866912 F 11/25/1961
Niswander Ebony 218384979 7468337166 F 12/3/1970
Overlees Minnesha 594664590 9411189605 F 8/5/1981
Jones Haley 692179128 9046757546 F 3/24/1968
Weiner Lee 111223333 2223334444 M 2/31/1978
/*
main class to create a Binary search tree
*/
import java.io.*;
import java.util.Scanner;
import java.util.regex.*;
import java.util.List;
import java.util.ArrayList;
public class AVLdatabase {
public static void main(String[] args) {
AVLTree anAVLTree = new AVLTree();
File file = new File("datafile.txt");
List<Person> dataArray = new ArrayList<Person>();
try {
Scanner scanner = new Scanner(file);
//read lines and place the data into person objects
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
Scanner lineScanner = new Scanner(line).useDelimiter("\t");
while (lineScanner.hasNext()) {
Person record = new Person(lineScanner.next(),lineScanner.next(),lineScanner.next(),lineScanner.next(),(lineScanner.next()).charAt(0),lineScanner.next());
System.out.print(record.getLast() + " ");
System.out.print(record.getFirst() + " ");
System.out.print(record.getSocial() + " ");
System.out.println();
Index index = new Index(record.getSocial(), dataArray.size());
dataArray.add(record);
anAVLTree.insert(index, record.getSocial());
System.out.println("The array index is " + (dataArray.size()-1));
}
}
}
catch (IOException e) {
System.out.print("No File");
}
}
}
Your height code looks fine. I would assume that your rotation code is causing one of your leaves to link back to an inner node.
E.g.:
A
/ \
B C
May be becoming:
B
/ \
C A
/ \
B C
with A still having a reference to B, which has a reference to A which has a reference to B, which has a reference to A, etc. The A -> B would, of course, be referencing the root B, but I can't picture that here.
You are the best person at debugging your own code, but I can provide some general suggestions:
Not sure if you're aware of this, but in the following code:
temp = node.getRight();
temp.setParent(node.getParent());
Correct me if I'm wrong, but temp is copied by reference, not by value. After these operations, node.getRight().getParent() will equal temp.getParent(). That's probably not the issue, but you should be aware of it.
Watch out for side effects. Whatever you did in the previous line affects the following lines.
Ditch the AVLNode parent; , as maintaining it introduces cruft. Bear in mind that you will probably need to make a recursive subroutine for delete() to keep track of the parent. Alternatively, make your accessor methods for AVLNode automatically maintain parent links.