Couldn't insert values in BinaryTree [duplicate] - java

This question already has answers here:
inserting in binary tree doesn't work using java
(2 answers)
Closed 2 years ago.
class bTree {
public class Node {
Node left;
Node right;
int val;
Node () {}
Node (int val){
this.val=val;
}
}
Node root;
public void insert(int val){
if (root == null){
root = new Node(val);
} else {
Node current = root;
// If val less than parent node's val go left
if (val <= root.val){
if (root.left == null){
root.left = new Node(val);
} else {
insert(val);
}
}
// If val greater than parent node's val go right
else {
if (root.right == null){
root.right = new Node(val);
} else {
insert(val);
}
} // inner else ends
} // outer else ends
} // insert() ends
public void displayTree(Node root){
if (root.left != null){
displayTree(root.left);
}
System.out.print(root.val + " - ");
if (root.right != null){
displayTree(root.right);
}
}
public static void main(String[] args) {
bTree bt = new bTree();
bt.insert(10);
bt.insert(30);
bt.insert(4);
bt.insert(5);
bt.displayTree(bt.root);
}
}
I was trying to implement a binary search tree and came across a problem inserting values in it. I have implemented it before making a Node main class but now nesting a Node class inside of a main class (like a LinkedList) is complicating it.
public void insert(int val){
if (root == null){
root = new Node(val);
} else {
Node current = root;
Here in this bit current is always getting value of root which causes not more than 3 items to be inserted. I am aware of this problem but couldn't get around it. Any redesign in the code would be greatly appreciated.

In your code you are not passing the reference of Node in insert() method to trace down at which node position you are in the current tree.
Currently you are able to insert only 3 items because for 3 items no recursion of insert(val) is getting used, but after 3 items you are using recursion of insert call and since in that you are not passing current node position this issue is coming.
Here is the working example of insertion in binary tree :
class bTree {
Node root;
public class Node {
Node left;
Node right;
int val;
Node () {}
Node (int val){
this.val=val;
}
}
public void insert(Node currnode, int val){
if(currnode == null) {
root = new Node(val);
return;
}
if(val <= currnode.val) {
if(currnode.left == null) {
currnode.left = new Node(val);
} else {
insert(currnode.left, val);
}
} else {
if(currnode.right == null) {
currnode.right = new Node(val);
} else {
insert(currnode.right, val);
}
}
}
public void displayTree(Node root){
if (root.left != null){
displayTree(root.left);
}
System.out.print(root.val + " - ");
if (root.right != null){
displayTree(root.right);
}
}
public static void main(String[] args) {
bTree bt = new bTree();
bt.insert(bt.root,10);
bt.insert(bt.root,30);
bt.insert(bt.root,4);
bt.insert(bt.root,5);
bt.displayTree(bt.root);
}
}

Related

Whats wrong in this BST implementation?

Why am I getting false while doing search(7)?
I tried recursive solution its working fine..
tried implementing with loop failed
public class BST {
class Node {
int data;
Node left , right;
public Node(int data) {
this.data = data;
this.left = this.right = null;
}
}
Node root;
public BST() {
this.root = null;
}
public void insert(int data) {
// create a new node and start iteration from root node
Node newNode = new Node(data);
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
currentNode = newNode;
break;
}
if (data < currentNode.data) { // if data is less go left
currentNode = currentNode.left;
} else if (data > currentNode.data) { // if data is greater go right
currentNode = currentNode.right;
} else { // do nothing for duplicates
break;
}
}
}
public boolean search(int data) {
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
return false;
}
if (data == currentNode.data) {
return true;
} else if (data < currentNode.data) {
currentNode = currentNode.left;
} else {
currentNode = currentNode.right;
}
}
}
public static void main(String... args) {
BST tree = new BST();
tree.insert(15);
tree.insert(7);
System.out.println(tree.search(7));
}
}
Problem is inside the insert method - you are not inserting the nodes correctly inside the tree.
If the tree is empty, you should assign to this.root, not currentNode. Assigning to currentNode has no affect on this.root.
Currently, your code isn't inserting any node inside the tree; it simply assigns the new node to the local variable of insert method, i.e. currentNode.
If the condition data < currentNode.data is true, then you need to check if the currentNode.left is null or not. If it is, then link the new node with the current node as shown below:
currentNode.left = newNode;
If currentNode.left is not null, then do the following:
currentNode = currentNode.left;
Currently, your code moves the currentNode to null and then assigns the newNode to the currentNode without a reference to its parent node in the tree.
Do step 2 for data > currentNode.data as well.
Change the implementation of the insert method as shown below:
public void insert(int data) {
Node newNode = new Node(data);
if (this.root == null) {
this.root = newNode;
return;
}
Node currentNode = this.root;
while (true) {
if (data < currentNode.data) {
if (currentNode.left == null) {
currentNode.left = newNode;
} else {
currentNode = currentNode.left;
}
} else if (data > currentNode.data) {
if (currentNode.right == null) {
currentNode.right = newNode;
} else {
currentNode = currentNode.right;
}
} else {
break;
}
}
}

Java - Return the node visited after node x in a pre-order traversal of BT

I am being asked to "Return the node visited after node x in a pre-order traversal of a binary tree" in Java for school. I have created a code to list all the nodes in pre-order, but I'm not sure how to print off a single node.
My first class to create the nodes is:
public class TreeNode {
int value; // The data in this node.
TreeNode left; // Pointer to the left subtree.
TreeNode right; // Pointer to the right subtree.
TreeNode parent; //Pointer to the parent of the node.
TreeNode(int value) {
this.value = value;
this.right = null;
this.left = null;
this.parent = null;
}
public void displayNode() { //Displays the value of the node.
System.out.println(value + " ");
}
I then have the class to build the binary tree. It also prints the whole tree in pre-order:
public class BTree2 {
TreeNode root; // the first node in the tree
public boolean isEmpty() // true if no links
{
return root == null;
}
private TreeNode addRecursive(TreeNode current, int value) {
if (current == null) {
return new TreeNode(value);
}
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
} else {
// value already exists
return current;
}
return current;
}
public void add(int value) {
root = addRecursive(root, value);
}
void printPreorder(TreeNode node) {
if (node == null) {
return;
}
System.out.print(node.value + " "); /* first print data of node */
printPreorder(node.left); /* then recur on left subtree */
printPreorder(node.right); /* now recur on right subtree */
}
void printPreorder() {
printPreorder(root);
}
This is where I get stuck: how do I print off the node that comes after a particular node, and not just the whole tree? I thought it would be:
public TreeNode findPreorder(int key) // find node with given key
{ // (assumes non-empty tree)
TreeNode current = root; // start at root
while (current.value == key) // while there is a match
{
current = current.left;
if (key < current.value) // go left?
{
current = current.right;
} else {
current = current.right; // or go right?
}
if (current == null) // if no child,
{
return null; // didn't find it
}
}
return current; // found it
}
But that's not working. This is my test code in my main:
public static void main(String[] args) {
BTree2 tree = new BTree2();
tree.root = new TreeNode(1);
tree.root.left = new TreeNode(2);
tree.root.right = new TreeNode(3);
tree.root.left.left = new TreeNode(4);
tree.root.left.right = new TreeNode(5);
System.out.println("Preorder traversal of binary tree is ");
tree.printPreorder();
System.out.println("the node after 1 is " + tree.findPreorder(1).value);
}
My output is:
Preorder traversal of binary tree is
1 2 4 5 3
the node after 1 is 5
Any ideas? Thanks!!
You can basically use the same function for visiting in pre order manner with some modifications:
void findNextInPreOrder(TreeNode node, int key) {
if (node == null) {
return;
}
if (node.value == key) {
if(node.left != null){
System.out.print("Next is on left: " + node.left.value);
} else if (node.right != null){
System.out.print("Next is on right: " + node.right.value);
} else {
System.out.print("There is no next node.");
}
}
findNextInPreOrder(node.left); /* then recur on left subtree */
findNextInPreOrder(node.right); /* now recur on right subtree */
}
Thank you!! I also added an 'else' statement since that seemed to help me a bit with the implementation:
void findNextInPreOrder(Node node, int key) {
if (node == null) {
return;
}
if (node.value == key) {
if (node.left != null) {
System.out.print("Next is on left: " + node.left.value);
} else if (node.right != null) {
System.out.print("Next is on right: " + node.right.value);
} else {
System.out.print("There is no next node.");
}
} else {
findNextInPreOrder(node.left, key);
/* then recur on left subtree */
findNextInPreOrder(node.right, key);
/* now recur on right subtree */
}
}

i can't print the linkedlist elements in reverse order using recursion

I am a beginner in java .I am implementing recursion in linked lists to print the elements in reverse order but i think that there is a semantic error in my code , check my code(especially that reverse method) thanks in an advance.
output:78 30 52 send after which item count from head u need to insert
package practice;
public class Linkedlist {
Node head;
public Linkedlist() {
head = null;
}
public void insert(int data) {
Node obj1 = new Node(data);
obj1.next = head;
head = obj1;
}
public void append(int data) {
Node newn = new Node(data);
if (head == null) {
newn.next = null;
head = newn;
return;
}
Node n = head;
while (n.next != null) {
n = n.next;
}
newn.next = null;
n.next = newn;
}
void delete(int data) {
if (head == null) {
return;
} else if (head.data == data) {
head = head.next;
return;
}
Node curr = head;
while (curr.next != null) {
if (curr.next.data == data) {
curr.next = curr.next.next;
}
curr = curr.next;
}
}
void insertAt(int count, int data) {
Node h = head;
if (count == 0) {
this.insert(data);
return;
}
while (h.next != null) {
if (count == 0) {
Node f = new Node(data);
f = h.next;
h = f;
return;
}
count--;
h = h.next;
}
}
public void reverse() {
if (head == null) {
System.out.println("null");
} else {
this.reverseRecursive(head);
}
}
private void reverseRecursive(Node nod) {
if (nod == null) {
return;
}
reverseRecursive(nod.next);
System.out.print(nod.data + " ");
}
class Node {
Node next;
int data;
public Node(int data) {
this.data = data;
}
}
public static void main(String args[]) {
Linkedlist obj = new Linkedlist();
obj.insert(78);
obj.insert(30);
obj.insert(52);
obj.reverse();
System.out.println("send after which item count from head u need to insert");
obj.insertAt(2, 5);
}
}
Looking at your code, I don't think there is anything wrong with your Reverse method. It is actually printing in reverse order. What's throwing you off is probably the way you are inserting the elements. Your insert() method is actually a stack. ( It inserts at top ). So after all insertions, head points to 52 and not 78. So when you print, the reverse list is printed as :
78 30 52
Also, your code needs a bit of formatting and should follow java conventions. Method names start with lower case and class names with uppercase. Good luck :)
In your LinkedList instead of using the insert method, which add an element at the head use the method append which adds the element at the end of the LinkedList and then call the reverse method.

finding a node location within a BST and adding it to the tree recursively

So i have 3 methods 1 that adds a node to the binary tree using the traverseAdd method, and another method which finds the location of where a value would be placed within the tree based on its parent node. I would like to eliminate the traverseAdd method and use the findLocation method within the add method to add the new value to the BST.
public void add(int val) {
/*Adds a new node to the binary tree after traversing the tree and figuring out where it belongs*/
Node nodeObjToAdd = new Node(val);
if(root == null){
//if node root is not null root = new node value
root = nodeObjToAdd;
}
Node nodeTraversed = root;
traverseAdd(nodeTraversed, nodeObjToAdd);
}
private void traverseAdd(Node node, Node nodeObjToAdd){
/*Traverses tree and finds a place to add the node to be added by comparing values of the left child and right child of the
* focus node*/
if(nodeObjToAdd.value < node.value){
if(node.leftChild == null){
node.leftChild = nodeObjToAdd;
}
else {
//if the val < the root.value set int he constructor
traverseAdd(node.leftChild, nodeObjToAdd);
}
}
else if(nodeObjToAdd.value > node.value) {
if (node.rightChild == null) {
node.rightChild = nodeObjToAdd;
} else {
traverseAdd(node.rightChild, nodeObjToAdd);
}
}
}
public Node findNodeLocation(Node rootNode, int val) {
/*returns where a the Node after which the value would be added.*/
if(val < rootNode.value && rootNode.leftChild != null){
return rootNode.leftChild;
}
if(val >= rootNode.value && rootNode.rightChild != null){
return rootNode.rightChild;
}
else
return this.root;
}
public void add(int val) {
if (root == null) {
root = new Node(val);
}
Node cur = root;
Node next = null;
while (true) {
next = findNodeLocation(cur, val);
if (next != cur) {
cur = next;
} else {
break;
}
}
if (val < cur.value) {
cur.leftChild = new Node(val);
} else {
cur.rightChild = new Node(val);
}
}
I think this should work

How do implement a breadth first traversal?

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;
}

Categories