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.
Related
I'm new to Java and programming in general. The code works, mostly. It can do everything except for when I input the following:
Sequence: d, e, f, a, b, c, g, h, i, j.
Search for: b or c
I can't seem to find any issue with the code but have narrowed it down to the insertNode module/class, it seems like when users key in a, b, c after d, e, f, only node a register on the left side.
import java.util.Arrays;
import java.util.Scanner;
import java.lang.reflect.Method;
public class BinarySearchTreeTestStackOverflow {
class Node {
String stringData;
Node leftChild;
Node rightChild;
Node(String stringData) {
this.stringData = stringData;
leftChild = rightChild = null;
}
}
//root node for the binary tree
Node root;
//Constructor method
public BinarySearchTreeTestStackOverflow() {
root = null;
}
//Insert method for new values in the tree
public void insert(String key) {
root = insertNode(root, key);
}
//Insert recursive call for inserting from the root, in the right place
public Node insertNode(Node node, String key) {
if (node == null) {
node = new Node(key);
return node;
}
if (key.compareTo(node.stringData) < 0) {
node.leftChild = insertNode(node.leftChild, key);
} else if (key.compareTo(root.stringData) > 0) {
node.rightChild = insertNode(node.rightChild, key);
}
return node;
}
//Find method asking for the node to find
public Node find(String key) { //takes user input and turns it into a node
Node node = findNode(root, key);
System.out.println("print key to find: " + key);
return node;
}
//Find recursive method using the root node.
public Node findNode(Node node, String key) {
if (key.compareTo(node.stringData) == 0) {
return node;
}
//check up on findNodeMethod
if (key.compareTo(node.stringData) <= 0) {
if (node.leftChild == null) {
return null;
} else {
return findNode(node.leftChild, key);
}
} else if (key.compareTo(node.stringData) > 0) {
if (node.rightChild == null) {
return null;
} else {
System.out.println("went right"); //toDelete
return findNode(node.rightChild, key);
}
}
return null;
}
public static void main(String[] args) {
BinarySearchTreeTestStackOverflow binaryTree = new BinarySearchTreeTestStackOverflow();
Scanner scanner = new Scanner(System.in);
for (int i = 1; i <= 10; i++) {
System.out.print("Enter string " + i + " for the tree: ");
binaryTree.insert(scanner.nextLine());
}
System.out.print("Enter the value to be searched: ");
String key = scanner.nextLine(); //correct, verified using - System.out.println("key to be searched: "+ key);
Node node = binaryTree.find(key);
if (node == null) {
System.out.println("The string does not exist");
} else {
System.out.println("Node " + node.stringData + " was found");
}
}
}
The issue is inside insertNode(). Instead of comparing with root:
else if (key.compareTo(root.stringData) > 0) {
node.rightChild = insertNode(node.rightChild, key);
}
you should compare with node:
else if (key.compareTo(node.stringData) > 0) {
node.rightChild = insertNode(node.rightChild, key);
}
I need to print all the nodes that are N level above all Leaf Nodes. I tried below approach, but now I am stuck and unable to proceed. Please help. I need to code only using Java 7 and no other versions.
For example, I have this path 1 --> 2 --> 3 --> 4, so in this case assuming 4 is my leaf node, node 3 is 1 level above 4 and node 2 is 2 levels above leaf node 4 and node 1 is 3 levels above leaf node 4.
Note: Please use only Java 7.
public class NNodeBeforeLeaf {
static Node root;
static class Node {
int data;
Node left, right;
Node(int data){
this.data = data;
left=right=null;
}
}
public static boolean isLeaf(Node n){
if(n.right == null && n.left == null)
return true;
return false;
}
public static void main(String[] args) {
int level = 2; // level N
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(8);
print(root, 0, level);
}
public static void print(Node n, int currLevel, int level){
if(n == null){
return;
}
if(!isLeaf(n)){
print(n.left, currLevel + 1, level);
print(n.right, currLevel + 1, level);
}
printNode(n, currLevel, level);
}
public static void printNode(Node n, int currLevel, int level){}
}
You have a miss in your structure to do this a Node know its child but not is parent so you need to build a structure that will give you this link : here is my proposition : i build a map that give me the parent associate to a node with method buildParentMap this function already list all the leaf in one pass to avoid a double iteration on your tree then i use this map to go up as many time as asked on each leaf i list just before here is a snippet
be carefull this code work but there is no security if your are trying to upper that root or if the same node is present in too child (but 2 Node with the same data wont be a problem)
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
public class NNodeBeforeLeaf {
static Node root;
static class Node {
int data;
Node left, right;
Node(int data) {
this.data = data;
left = right = null;
}
#Override
public String toString() {
return "Node : " + data;
}
}
public static boolean isLeaf(Node n) {
if (n.right == null && n.left == null)
return true;
return false;
}
public static void main(String[] args) {
int level = 2; // level N
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(8);
print(root, 0, level);
int levelToUp = 1;
HashSet<Node> result = getUpper(levelToUp, root);
System.out.println(Arrays.toString(result.toArray()));
}
private static HashSet<Node> getUpper(int levelToUp, Node node) {
HashMap<Node, Node> parenttMap = new HashMap<Node, Node>();
LinkedList<Node> leafs = new LinkedList<Node>();
buildParentMap(node, parenttMap, leafs);
HashSet<Node> result = new HashSet<>();
for (Node leaf : leafs) {
result.add(getUpperLevel(leaf, levelToUp, parenttMap));
}
return result;
}
private static Node getUpperLevel(Node leaf, int i, HashMap<Node, Node> parenttMap) {
Node tmp = leaf;
while (i > 0) {
i--;
tmp = parenttMap.get(tmp);
}
return tmp;
}
private static void buildParentMap(Node root2, HashMap<Node, Node> hashMap, LinkedList<Node> leaf) {
if (root2 == null) {
return;
} else if (isLeaf(root2)) {
leaf.add(root2);
} else {
hashMap.put(root2.left, root2);
buildParentMap(root2.left, hashMap, leaf);
hashMap.put(root2.right, root2);
buildParentMap(root2.right, hashMap, leaf);
}
}
public static void print(Node n, int currLevel, int level) {
if (n == null) {
return;
}
printNode(n, currLevel, level);
if (!isLeaf(n)) {
print(n.left, currLevel + 1, level);
print(n.right, currLevel + 1, level);
}
}
public static void printNode(Node n, int currLevel, int level) {
String output = "";
for (int i = 0; i < currLevel; i++) {
output += "\t";
}
System.out.println(output + n);
}
}
PLEASE READ MY COMMENT FIRST
Since the nodes in your program store data only for the nodes below them, I couldn't really find a way of actually going up the tree ':), but I could think of this work around, basically what you can do is, each time you need to go up by n levels you can traverse down from the root to (curLevel - n) here is a sample program that does this (it prints all the nodes at a level which is n above the current level, i hope this is what you meant):
class tree{
static class Node{
int data;
Node left;
Node right;
Node(int data){
this.data = data;
left = null;
right = null;
}
}
static Node root;
public static boolean isLeaf(Node n){
if(n.left == null && n.right == null)
return true;
return false;
}
public static void goDownTillLevel(Node n, int level){
int l = level;
if(n != null){
if(level == 0) {
System.out.println(n.data);
}
else{
if(!isLeaf(n)){
goDownTillLevel(n.left, --level);
level = l; //since by the time the above function calls finished, level had been reduced to 0
goDownTillLevel(n.right, --level);
}
}
}
}
public static void nLevelsAbove(Node n, int curLevel, int level){
goDownTillLevel(root, (curLevel - level - 1));
}
public static void main(String args[]){
int curLevel = 0;
root = new Node(1);
curLevel++;
root.left = new Node(2);
root.right = new Node(2);
curLevel++;
root.left.left = new Node(3);
root.left.right = new Node(3);
root.right.left = new Node(3);
Node n = new Node(3);
root.right.right = n;
curLevel++;
nLevelsAbove(n, curLevel, 1);
}
}
Though I'd like to add that if going up is one of your concerns, don't use this node structure, instead add another variable to the node, a reference to the node right above it, that way this could be made much easier and shorter.
The output of the above code is:
2
2
I think that the implementation of public static boolean isLeaf(Node n) is wrong, it should check only if right is null otherwise it is not a node, either a leaf
To get the current level of node, you can try with this code
int level = 0;
while(node.right != null) {
level++;
node = node.right;
}
System.out.println("current level node: " + level);
Your structure is not able to determine the height of the current node, except when traversing from bottom to top. In order to achieve this, you have to traverse to the leafs first.
Each recursion (bottom up now) should then return it's heights. As youre not stating if your tree is a full binary tree, a node can have multiple heights depending on his children. If the heights match the desired height, the node can be printed.
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class NNodeBeforeLeaf {
static Node root;
static class Node {
int data;
Node left, right;
Node(int data) {
this.data = data;
left = right = null;
}
}
public static boolean isLeaf(Node n) {
return n.right == null && n.left == null;
}
public static void main(String[] args) {
int level = 2; // level N
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(8);
print(root, level);
}
public static void print(Node n, int level) {
traversAndPrint(n, level);
}
private static Set<Integer> traversAndPrint(Node n, int levelToPrint) {
if (isLeaf(n)) return Collections.singleton(0); // We are a leaf, so we have height 0
final Set<Integer> childrenHeights = new HashSet<>();
// are no leaf, so we have to get the heights of our children
if (n.right != null) childrenHeights.addAll(traversAndPrint(n.right, levelToPrint));
if (n.left != null) childrenHeights.addAll(traversAndPrint(n.left, levelToPrint));
assert !childrenHeights.isEmpty();
// And increase these heights
final Set<Integer> selfHeights = new HashSet<>();
for (Integer childrenHeigth : childrenHeights) {
final int selfHeight = childrenHeigth + 1;
selfHeights.add(selfHeight);
}
// If we have the desired height, print
if (selfHeights.contains(levelToPrint)) printNode(n);
return selfHeights; // return our heights
}
public static void printNode(Node n) {
// Do whatever you want
System.out.println(n.data);
}
}
I found another approach. I put all nodes in a list. For each level up I remove the leaf nodes in that list. A leaf node in the list is defined as a node with left=null and right=null or if they are not null left and right should not be in the list. After the level ups I print the now leaf nodes in the list.
public class NNodeBeforeLeaf {
static Node root;
static class Node {
int data;
Node left, right;
Node(int data) {
this.data = data;
left = right = null;
}
}
public static boolean isLeaf(Node n) {
if ((n.right == null) && (n.left == null)) {
return true;
}
return false;
}
public static void main(String[] args) {
int level = 2; // level N
root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(8);
printNodes(getNodesNLevelAboveLeafs(root, level));
}
public static void printNodes(List<Node> nodes) {
for (Node n : nodes) {
System.out.println(n.data);
}
}
public static List<Node> getNodesNLevelAboveLeafs(Node root, int level) {
List<Node> allNodes = listAllNodes(root);
for (int i = 0; i < level; i++) {
allNodes.removeAll(getLeafNodes(allNodes));
}
return getLeafNodes(allNodes);
}
private static List<Node> getLeafNodes(List<Node> allNodes) {
List<Node> leafs = new ArrayList<>();
for (Node n : allNodes) {
if (((n.left == null) || !allNodes.contains(n.left))
&& ((n.right == null) || !allNodes.contains(n.right))) {
leafs.add(n);
}
}
return leafs;
}
private static List<Node> listAllNodes(Node node) {
List<Node> nodes = new ArrayList<>();
nodes.add(node);
if (node.left != null) {
nodes.addAll(listAllNodes(node.left));
}
if (node.right != null) {
nodes.addAll(listAllNodes(node.right));
}
return nodes;
}
}
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 need to build a balanced binary search tree. So far my program inserts the numbers from 1 to 26, but my program does not build it into a balanced binary search tree. If anyone could look at my code and help me out it would be much appreciated.
public class TreeNode {
TreeNode leftTreeNode, rightTreeNode;// the nodes
int data;
//int size;
public TreeNode(){//Constructer
leftTreeNode = null;
rightTreeNode = null;
}
public TreeNode(int newData){//Constructer with new Data coming in for comparison
leftTreeNode = null;
rightTreeNode = null;
data = newData;
}
public TreeNode getLeft(){
return leftTreeNode;
}
public TreeNode getRight(){
return rightTreeNode;
}
public void setLeft(TreeNode leftTreeNode){
this.leftTreeNode = leftTreeNode;
}
public void setRight(TreeNode rightTreeNode){
this.rightTreeNode = rightTreeNode;
}
public int getData(){
return data;
}
// public boolean isEmpty(){//Checking to see if the the root is empty
// if(size == 0) return true;
// else return false;
public void print(){
System.out.println("Data is: " + getData());
}
}
// public void traverse (Node root){ // Each child of a tree is a root of its subtree.
// if (root.getLeft() != null){
// traverse (root.getLeft());
// }
// System.out.println(root.data);
// if (root.getRight() != null){
// traverse (root.getRight());
// }
//}
public class BinarySearchTree {
TreeNode root;
public BinarySearchTree(){
root = null;
}
public TreeNode getRoot(){
return root;
}
public void insert(int data) { //Insert method checking to see where to put the nodes
TreeNode node1 = new TreeNode(data);
if (root == null) {
root = node1;
}
else{
TreeNode parIns = root;//Parent
TreeNode insNode = root;//Insertion Node
while(insNode != null){
parIns = insNode;
if(data < insNode.getData()){//If the data is less than the data coming in place it on the left
insNode = insNode.getLeft();
}else{//Place it on the right
insNode = insNode.getRight();
}
}//Searching where to put the node
if(data < parIns.getData()){
parIns.setLeft(node1);
}else{
parIns.setRight(node1);
}
}
}
public void printInorder(TreeNode n){
if(n != null){
printInorder(n.getLeft());//L
n.print();//N
printInorder(n.getRight());//R
}
}
// public TreeNode balance(tree, int start, int end){
// if(start > end) return null;
// int mid = (start + end) /2;
// TreeNode node;
// TreeNode leftChild;
// TreeNode rightChild;
//
// if(node <= mid){
// leftChild = balance(arr[mid -1], start, end);/*Make the left child if the node coming in is
// less than the mid node */
//
//
// }else{
// rightChild = balance(arr[mid]+1, start, end);/*Make the rigth child if the node is
// greater than the mid node*/
//
// }
// return node;
// }
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
tree.insert(1);
tree.insert(2);
tree.insert(3);
tree.insert(4);
tree.insert(5);
tree.insert(6);
tree.insert(7);
tree.insert(8);
tree.insert(9);
tree.insert(10);
tree.insert(11);
tree.insert(12);
tree.insert(13);
tree.insert(14);
tree.insert(15);
tree.insert(16);
tree.insert(17);
tree.insert(18);
tree.insert(19);
tree.insert(20);
tree.insert(21);
tree.insert(22);
tree.insert(23);
tree.insert(24);
tree.insert(25);
tree.insert(26);
tree.printInorder(tree.getRoot());
}
}
//for(int i = 1; i <= 26; i++)
//tree.insert(i);
public void balance(TreeNode tree, int start, int end){
TreeNode tree1 = new TreeNode(data);
if(start <= end){
int mid = (start + end) /2;
//TreeNode node;
TreeNode leftChild;
TreeNode rightChild;
if(tree1.getData() <= mid){
leftChild = balance(tree1(mid -1), start, end);/*Make the left child if the node coming in is
less than the mid node */
}else{
rightChild = balance(tree1(mid+1), start, end);/*Make the rigth child if the node is
greater than the mid node*/
}
}
}
How can I fix the balance function to properly balance my tree?
Since your tree does not self-balance, whether or not it's balanced will depend on the order of insertion of the elements.
If you want your tree to be balanced regardless, you will need to take care of the balancing in your class. For example, take a look at the Red-Black Tree data structure.
public class BinarySearchTree {
TreeNode root;
public BinarySearchTree(){
root = new TreeNode();
}
public TreeNode getRoot(){
return root;
}
public void insert(int data) {
root = insert(root, data);
}//Insert method checking to see where to put the nodes
// public void insert(TreeNode node, int data){
// TreeNode node1 = new TreeNode(data);
// if (root == null) {
// root = node1;
// }
// else{
// TreeNode parIns = root;//Parent
// TreeNode insNode = root;//Insertion Node
//
// while(insNode != null){
// parIns = insNode;
//
// if(data < insNode.getData()){//If the data is less than the data coming in place it on the left
// insNode = insNode.getLeft();
// }else{//Place it on the right
// insNode = insNode.getRight();
// }
// }//Searching where to put the node
//
// if(data < parIns.getData()){
// parIns.setLeft(node1);
// }else{
// parIns.setRight(node1);
// }
//
// }
// }
private TreeNode insert(TreeNode node, int data) {
if(root.data == 0)
root.data = data;
else if (node==null) {
node = new TreeNode(data);
}
else {
if (data <= node.data) {
node.leftTreeNode = insert(node.leftTreeNode, data);
}
else {
node.rightTreeNode = insert(node.rightTreeNode, data);
}
}
return(node); // in any case, return the new pointer to the caller
}
public void printPreOrder(){
printPreOrder(root);
}
public void printPreOrder(TreeNode n){
if(n != null){
n.print();//N
printPreOrder(n.getLeft());//L
printPreOrder(n.getRight());//R
}
}
public TreeNode balance(int[] a, int start, int end){
TreeNode node = new TreeNode();
if(start <= end){
int mid = start + (end - start) /2;
node.data = a[mid];
if(root.data == 0)
root = node;
node.leftTreeNode = balance(a, start, mid -1);/*Make the left child if the node coming in is
less than the mid node */
node.rightTreeNode = balance(a, mid + 1, end);/*Make the rigth child if the node is
greater than the mid node*/
}
else{
return null;
}
return node;
}
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
//int[] a = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,21,22,23,24,25,26};
int[] a = new int[26];
for(int i = 0; i < 26; i++){
a[i] = i + 1;
}
for(int i = 1; i <= 26; i++)
tree.insert(i);
tree.printPreOrder();
BinarySearchTree tree2 = new BinarySearchTree();
tree2.balance(a, 0, 25);
System.out.println("Now I am going to balance my tree");
tree2.printPreOrder();
}
}
public class TreeNode {
TreeNode leftTreeNode, rightTreeNode;// the nodes
int data;
//int size;
public TreeNode(){//Constructer
leftTreeNode = null;
rightTreeNode = null;
data = 0;
}
public TreeNode(int newData){//Constructer with new Data coming in for comparison
leftTreeNode = null;
rightTreeNode = null;
data = newData;
}
public TreeNode getLeft(){
return leftTreeNode;
}
public TreeNode getRight(){
return rightTreeNode;
}
public void setLeft(TreeNode leftTreeNode){
this.leftTreeNode = leftTreeNode;
}
public void setRight(TreeNode rightTreeNode){
this.rightTreeNode = rightTreeNode;
}
public int getData(){
return data;
}
// public boolean isEmpty(){//Checking to see if the the root is empty
// if(size == 0) return true;
// else return false;
public void print(){
System.out.println("Data is: " + getData());
}
}
For an assignment, we were instructed to create a priority queue implemented via a binary heap, without using any built-in classes, and I have done so successfully by using an array to store the queued objects. However, I'm interested in learning how to implement another queue by using an actual tree structure, but in doing so I've run across a bit of a problem.
How would I keep track of the nodes on which I would perform insertion and deletion? I have tried using a linked list, which appends each node as it is inserted - new children are added starting from the first list node, and deleted from the opposite end. However, this falls apart when elements are rearranged in the tree, as children are added at the wrong position.
Edit: Perhaps I should clarify - I'm not sure how I would be able to find the last occupied and first unoccupied leaves. For example, I would always be able to tell the last inserted leaf, but if I were to delete it, how would I know which leaf to delete when I next remove the item? The same goes for inserting - how would I know which leaf to jump to next after the current leaf has both children accounted for?
A tree implementation of a binary heap uses a complete tree [or almost full tree: every level is full, except the deepest one].
You always 'know' which is the last occupied leaf - where you delete from [and modifying it is O(logn) after it changed so it is not a problem], and you always 'know' which is the first non-occupied leaf, in which you add elements to [and again, modifying it is also O(logn) after it changed].
The algorithm idea is simple:
insert: insert element to the first non-occupied leaf, and use heapify [sift up] to get this element to its correct place in the heap.
delete_min: replace the first element with the last occupied leaf, and remove the last occupied leaf. then, heapify [sift down] the heap.
EDIT: note that delete() can be done to any element, and not only the head, however - finding the element you want to replace with the last leaf will be O(n), which will make this op expensive. for this reason, the delete() method [besides the head], is usually not a part of the heap data structure.
I really wanted to do this for almost a decade.Finally sat down today and wrote it.Anyone who wants it can use it.I got inspired by Quora founder to relearn Heap.Apparently he was asked how would you find K near points in a set of n points in his Google phone screen.Apparently his answer was to use a Max Heap and to store K values and remove the maximum element after the size of the heap exceeds K.The approach is pretty simple and the worst case is nlog K which is better than n^2 in most sorting cases.Here is the code.
import java.util.ArrayList;
import java.util.List;
/**
* #author Harish R
*/
public class HeapPractise<T extends Comparable<T>> {
private List<T> heapList;
public List<T> getHeapList() {
return heapList;
}
public void setHeapList(List<T> heapList) {
this.heapList = heapList;
}
private int heapSize;
public HeapPractise() {
this.heapList = new ArrayList<>();
this.heapSize = heapList.size();
}
public void insert(T item) {
if (heapList.size() == 0) {
heapList.add(item);
} else {
siftUp(item);
}
}
public void siftUp(T item) {
heapList.add(item);
heapSize = heapList.size();
int currentIndex = heapSize - 1;
while (currentIndex > 0) {
int parentIndex = (int) Math.floor((currentIndex - 1) / 2);
T parentItem = heapList.get(parentIndex);
if (parentItem != null) {
if (item.compareTo(parentItem) > 0) {
heapList.set(parentIndex, item);
heapList.set(currentIndex, parentItem);
currentIndex = parentIndex;
continue;
}
}
break;
}
}
public T delete() {
if (heapList.size() == 0) {
return null;
}
if (heapList.size() == 1) {
T item = heapList.get(0);
heapList.remove(0);
return item;
}
return siftDown();
}
public T siftDown() {
T item = heapList.get(0);
T lastItem = heapList.get(heapList.size() - 1);
heapList.remove(heapList.size() - 1);
heapList.set(0, lastItem);
heapSize = heapList.size();
int currentIndex = 0;
while (currentIndex < heapSize) {
int leftIndex = (2 * currentIndex) + 1;
int rightIndex = (2 * currentIndex) + 2;
T leftItem = null;
T rightItem = null;
int currentLargestItemIndex = -1;
if (leftIndex <= heapSize - 1) {
leftItem = heapList.get(leftIndex);
}
if (rightIndex <= heapSize - 1) {
rightItem = heapList.get(rightIndex);
}
T currentLargestItem = null;
if (leftItem != null && rightItem != null) {
if (leftItem.compareTo(rightItem) >= 0) {
currentLargestItem = leftItem;
currentLargestItemIndex = leftIndex;
} else {
currentLargestItem = rightItem;
currentLargestItemIndex = rightIndex;
}
} else if (leftItem != null && rightItem == null) {
currentLargestItem = leftItem;
currentLargestItemIndex = leftIndex;
}
if (currentLargestItem != null) {
if (lastItem.compareTo(currentLargestItem) >= 0) {
break;
} else {
heapList.set(currentLargestItemIndex, lastItem);
heapList.set(currentIndex, currentLargestItem);
currentIndex = currentLargestItemIndex;
continue;
}
}
}
return item;
}
public static void main(String[] args) {
HeapPractise<Integer> heap = new HeapPractise<>();
for (int i = 0; i < 32; i++) {
heap.insert(i);
}
System.out.println(heap.getHeapList());
List<Node<Integer>> nodeArray = new ArrayList<>(heap.getHeapList()
.size());
for (int i = 0; i < heap.getHeapList().size(); i++) {
Integer heapElement = heap.getHeapList().get(i);
Node<Integer> node = new Node<Integer>(heapElement);
nodeArray.add(node);
}
for (int i = 0; i < nodeArray.size(); i++) {
int leftNodeIndex = (2 * i) + 1;
int rightNodeIndex = (2 * i) + 2;
Node<Integer> node = nodeArray.get(i);
if (leftNodeIndex <= heap.getHeapList().size() - 1) {
Node<Integer> leftNode = nodeArray.get(leftNodeIndex);
node.left = leftNode;
}
if (rightNodeIndex <= heap.getHeapList().size() - 1) {
Node<Integer> rightNode = nodeArray.get(rightNodeIndex);
node.right = rightNode;
}
}
BTreePrinter.printNode(nodeArray.get(0));
}
}
public class Node<T extends Comparable<?>> {
Node<T> left, right;
T data;
public Node(T data) {
this.data = data;
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
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) {
String nodeData = String.valueOf(node.data);
if (nodeData != null) {
if (nodeData.length() == 1) {
nodeData = "0" + nodeData;
}
}
System.out.print(nodeData);
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 < 2 * 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;
}
}
Please note that BTreePrinter is a code I took somewhere in Stackoverflow long back and I modified to use with 2 digit numbers.It will be broken if we move to 3 digit numbers and it is only for simple understanding of how the Heap structure looks.A fix for 3 digit numbers is to keep everything as multiple of 3.
Also due credits to Sesh Venugopal for wonderful tutorial on Youtube on Heap data structure
public class PriorityQ<K extends Comparable<K>> {
private class TreeNode<T extends Comparable<T>> {
T val;
TreeNode<T> left, right, parent;
public String toString() {
return this.val.toString();
}
TreeNode(T v) {
this.val = v;
left = null;
right = null;
}
public TreeNode<T> insert(T val, int position) {
TreeNode<T> parent = findNode(position/2);
TreeNode<T> node = new TreeNode<T>(val);
if(position % 2 == 0) {
parent.left = node;
} else {
parent.right = node;
}
node.parent = parent;
heapify(node);
return node;
}
private void heapify(TreeNode<T> node) {
while(node.parent != null && (node.parent.val.compareTo(node.val) < 0)) {
T temp = node.val;
node.val = node.parent.val;
node.parent.val = temp;
node = node.parent;
}
}
private TreeNode<T> findNode(int pos) {
TreeNode<T> node = this;
int reversed = 1;
while(pos > 0) {
reversed <<= 1;
reversed |= (pos&1);
pos >>= 1;
}
reversed >>= 1;
while(reversed > 1) {
if((reversed & 1) == 0) {
node = node.left;
} else {
node = node.right;
}
reversed >>= 1;
}
return node;
}
public TreeNode<T> remove(int pos) {
if(pos <= 1) {
return null;
}
TreeNode<T> last = findNode(pos);
if(last.parent.right == last) {
last.parent.right = null;
} else {
last.parent.left = null;
}
this.val = last.val;
bubbleDown();
return null;
}
public void bubbleDown() {
TreeNode<T> node = this;
do {
TreeNode<T> left = node.left;
TreeNode<T> right = node.right;
if(left != null && right != null) {
T max = left.val.compareTo(right.val) > 0 ? left.val : right.val;
if(max.compareTo(node.val) > 0) {
if(left.val.equals(max)) {
left.val = node.val;
node.val = max;
node = left;
} else {
right.val = node.val;
node.val = max;
node = right;
}
} else {
break;
}
} else if(left != null) {
T max = left.val;
if(left.val.compareTo(node.val) > 0) {
left.val = node.val;
node.val = max;
node = left;
} else {
break;
}
} else {
break;
}
} while(true);
}
}
private TreeNode<K> root;
private int position;
PriorityQ(){
this.position = 1;
}
public void insert(K val) {
if(val == null) {
return;
}
if(root == null) {
this.position = 1;
root = new TreeNode<K>(val);
this.position++;
return ;
}
root.insert(val, position);
position++;
}
public K remove() {
if(root == null) {
return null;
}
K val = root.val;
root.remove(this.position-1);
this.position--;
if(position == 1) {
root = null;
}
return val;
}
public static void main(String[] args) {
PriorityQ<Integer> q = new PriorityQ<>();
System.out.println(q.remove());
q.insert(1);
q.insert(11);
q.insert(111);
q.insert(1111);
q.remove();
q.remove();
q.remove();
q.remove();
q.insert(2);
q.insert(4);
}
}