I'm trying to implement a binary tree, but its just not taking the root. Any ideas? It looks like the root should be inserting fine, but I'm just getting a null when I print it. Am I trying to add only temporary nodes to the tree that don't "stick"?
public class tree {
public static void main(String args[]){
Treeb tree = new Treeb();
tree.add(10);
tree.add(20);
tree.add(2);
tree.add(6);
tree.printTree();
}
}
class Node{
int data;
Node left;
Node right;
public Node(int data){
this.data = data;
left = null;
right = null;
}
Node getLeft(){
return left;
}
Node getRight(){
return right;
}
}
class Treeb{
Node root;
Treeb(){
root = null;
}
void add(int n){
addNode(n, root);
}
void addNode(int n, Node vert){
if(vert == null){
vert = new Node(n);
}
else if(vert.left.data < n){
if(vert.left == null){
vert.left = new Node(n);
}
else{
addNode(n, vert.left);
}
}
else if(vert.right.data >= n){
if(vert.right == null){
vert.right = new Node(n);
}
else{
addNode(n,vert.right);
}
}
}
void printTree(){
if(root != null){
printChild(root);
}
System.out.println(root);
}
void printChild(Node leaf){
System.out.print(leaf.data);
if(leaf.left != null){
printChild(leaf.getLeft());
}
if(leaf.right != null){
printChild(leaf.getRight());
}
}
}
You are assigning vert a new reference, but not root, that's why it stays null.
Your method addNode(int, Node) isn't working.
First:
if(vert == null){
vert = new Node(n);
}
You're assigning the new node to a local variable. Thus, the new Node gets discarded at the end of the method.
Second:
}
else if(vert.left.data < n){
// code
}
else if(vert.right.data >= n){
vert.left and vert.rightcan be null, so you would get an NPE when vert is not null.
getLeft() and getRight() can (and will) return null sometime. You should make sure in your printChild() that leaf itself is not null. (You're probably getting NPE in if(leaf.left != null) since leaf is null), you might also want to reconsider your tree construction again, root is null in your case.
Related
I am trying to insert in a binary search tree using recursion and then print it preorderly using this specific code, but I have only root as output,why?Is this because each time stack(after each call) is popping off thus removing new nodes?(This is a java code)
class node{
int data;
node left;
node right;
node(int key){
data = key;
left = right = null;
}
}
class bst{
node root;
node temp;
node last;
bst(){
root = null;
}
bst(int key){
root = new node(key);
}
void Insert(node r,int value){
temp = r;
if(temp == null){
if(root == null){
root = new node(value);
root.data = value;
return;
}
temp = new node(value);
temp.data = value;
return;
}
else{
if(value > temp.data){
Insert(temp.right,value);
return;
}
else{
Insert(temp.left,value);
return;
}
}
}
}
class test{
static void in_order(node root){
if(root == null){
return;
}
in_order(root.left);
System.out.println(root.data+" ");
in_order(root.right);
}
public static void main(String[] args){
bst tree = new bst();
tree.Insert(tree.root,45);
tree.Insert(tree.root,39);
tree.Insert(tree.root,12);
tree.Insert(tree.root,59);
test.in_order(tree.root);
}
}
The reason you are only getting a single integer for an output is because the first Insert call correctly adds the element to the tree, but subsequent calls fail because you overwrite the data member temp to null when you recursively insert to the left or right. Thus the second branch of your first if statement never gets executed.
You don't actually need the variable temp here. A common convention is to have a private, recursive member function that takes the root of the tree as a parameter returns the modified tree, and assign the return value to root in a public member function.
public void Insert(int value) {
root = Insert(root, value);
}
private node Insert(node r, int value) {
if (r == null) {
r = new node(value);
}
else if (value > r.data) {
r.right = Insert(r.right, value);
}
else {
r.left = Insert(r.left, value);
}
return r;
}
This means that you only have to call it like tree.Insert(x).
The following is a simple implementation of Binary search tree using java. However, the code always outputs "BST empty!!" despite inserting elements. Where am I going wrong? I suspect I'm going wrong with recursion. Any help is greatly appreciated.
public class BinarySearchTree {
NODE root;
BinarySearchTree(){
root = null;
}
void insert(NODE nodeptr,int key){
if(root == null){
nodeptr = new NODE(key);
return;
}
if(nodeptr == null){
nodeptr = new NODE(key);
return;
}
if(key <= nodeptr.data){
insert(nodeptr.left,key);
}
else{
insert(nodeptr.right,key);
}
}
void inorder(NODE nodeptr){
if(nodeptr == null){
System.out.println("BST empty!!");
return;
}
inorder(nodeptr.left);
System.out.println(nodeptr.data + " ");
inorder(nodeptr.right);
}
/*driver program*/
public static void main(String args[]){
int[] a = {20,30,40,24,39};
BinarySearchTree bst = new BinarySearchTree();
for (int i: a){
bst.insert(bst.root,i);
}
bst.inorder(bst.root);
}
}
class NODE{
int data;
NODE left,right;
NODE(int data){
this.data = data;
left = null;
right = null;
}
}
Your insert method never assigns value to the root, so it remains null.
If I understand your code, your insert should look like this :
void insert(NODE nodeptr,int key){
if(root == null){
root = new NODE(key);
return;
}
if(nodeptr == null){
insert (root, key);
return;
}
if(key <= nodeptr.data){
if (nodeptr.left != null)
insert(nodeptr.left,key);
else
nodeptr.left = new NODE(key);
}
else{
if (nodeptr.right != null)
insert(nodeptr.right,key);
else
nodeptr.right = new NODE(key);
}
}
If the root is null, ignore the passed nodeptr and put key at the root of the tree.
If nodeptr is null, try to insert the new key starting at the root of the tree.
otherwise, once you find a null nodeptr.left or nodeptr.right, you must put the new key there, because if you make another recursive call, you would be passing a null Node to it, and the recursion would never end.
Expanding from Erans answer you could change it to:
public void insert(int key){
if(root == null){
root = new NODE(key);
return;
}
insert(root,key)
}
private void insert(NODE nodeptr,int key){
if(key <= nodeptr.data){
if(nodeptr.left == null){
nodeptr.left = new NODE(key)
}
else {
insert(nodeptr.left,key);
}
}
else{
if(nodeptr.right == null){
nodeptr.right = new NODE(key)
}
else {
insert(nodeptr.right,key);
}
}
}
Edit: As he has added his own code now its just a matter of what style you like better. A single method or two methods from which the public one has only one parameter.
I wanted my insert method something like this. Got it to working finally. Thank you all for your precious time.
NODE insert(NODE nodeptr,int key){
if(nodeptr == null){
nodeptr = new NODE(key);
}
else if(key <= nodeptr.data){
nodeptr.left = insert(nodeptr.left,key);
}
else{
nodeptr.right = insert(nodeptr.right,key);
}
return nodeptr;
}
I would call insert method from main something like this:
bst.root = bst.insert(bst.root,i);
Solution i am pasting comes from this Geek URL
Its written in C, so i tried converting it in JAVA as below - (please do correct me if m wrong, i am not c/c++ person)
Program
// A simple recursive function to convert a given Binary tree to Doubly
// Linked List
// root --> Root of Binary Tree
// head --> Pointer to head node of created doubly linked list
public void BinaryTree2DoubleLinkedList(BTNodes root, BTNodes head)
{
if(root == null)
return;
// Initialize previously visited node as NULL. This is
// declared outside the recursive function so that the same value
// is accessible in all recursive calls
prev = null;
// Recursively convert left subtree
BinaryTree2DoubleLinkedList(root.getLeft(), head);
//set head of LL if not set
if(orgHead == null)
orgHead = root;
// Now convert this node
if (prev == null)
head = root;
else
{
root.setLeft(prev);
prev.setRight(root);
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root.getRight(), head);
}
Tree In Consideration
10
/ \
5 15
/ \ / \
2 7 12 18
/
1
/
0
Problem
This program returns output :
0 1 2 5 7 10 15 18
As you can see, 12 is missing from the code.I tried to dry run it many times but still not able to find out the real issue.....I tried searching for different solutions but most of them traverse in the part-converted-LL which increases the time complexity.
In original C code function prototype is following:
void BinaryTree2DoubleLinkedList(node *root, node **head)
**head mean double pointer, head value can be changed within function using *head. In java you can't modify function parameter because they are always copied, but you can modify array element.
So please try following code:
BTNode prev;
void BinaryTree2DoubleLinkedList(BTNodes root, BTNodes[] head)
{
// Base case
if (root == null) return;
// Initialize previously visited node as NULL. This is
// static so that the same value is accessible in all recursive
// calls
// Recursively convert left subtree
BinaryTree2DoubleLinkedList(roor.getLeft(), head);
// Now convert this node
if (prev == null)
head[0] = root;
else
{
root.setLeft(prev);
prev.setRight(root);
}
prev = root;
// Finally convert right subtree
BinaryTree2DoubleLinkedList(root.getRight(), head);
}
Initial call should look like:
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
// result is in head[0]
To avoid ugly allocation for head element better to make additional function like following:
BTNodes BinaryTree2DoubleLinkedList(BTNodes root) {
BTNodes[] head = new BTNodes[1];
BinaryTree2DoubleLinkedList(root, head);
return head[0];
}
Converting Binary Search tree into Doubly Linked List is kind of easy task if we use left and right fields of Node.
Recursion helps us here.
First, go down till the left node. Assign the left most leaf node as prev and also as head of list.
Once control come back from leaf node to its parent, assign current node i.e. parent of left node as right of prev and left of current node as leaf node.
Same is goes for right leaf child of current node.
Once we are out of complete recursion, we will have our doubly linked list, with listHead and listTail.
{
Node prev = null;
Node listHead = null;
Node listTail = null;
public void convertToList(Node node)
{
if(node == null)
return;
convertToList(node.left);
if(listHead == null)
listHead = node;
if(prev == null)
prev = node;
else
{
node.left = prev;
prev.right = node;
}
prev = node;
convertToList(node.right);
if(node.right == null)
listTail = node;
}
public void printList()
{
Node node = listHead;
System.out.println("Doubly Linked List from Head: ");
while(node!= null)
{
System.out.print(node.data+" ");
node = node.right;
}
}
public void printListFromTail()
{
Node node = listTail;
System.out.println("Doubly Linked List from Tail: ");
while(node!= null)
{
System.out.print(node.data+" ");
node = node.left;
}
}
}
For any google visitor, i worked out a way to avoid head[0] - (this might pose problems if the program is called through different object for different trees, as head[0] may get overwritten)
Here is the implementation :
Trick is to remove prev = null; from the code and initialize tempHead = null and prev = null in the calling function, not in recursive call.
void BinaryTree2DoubleLinkedList(BTNodes root, BTNodes tempHead)
{
// Base case
if (root == null) return; //optional, not needed in fact
// Recursively convert left subtree
if(root.getLeft() != null) //purely to reduce number of traversed node
BinaryTree2DoubleLinkedList(root.getLeft(), tempHead);
//set Original Head of the List, this would be leftmost
//leaf in the tree
if(orgHead == null)
orgHead = root;
// Now convert this node
if (prev == null)
tempHead = root;
else
{
root.setLeft(prev);
prev.setRight(root);
}
prev = root;
// Finally convert right subtree
if(root.getRight() != null) //purely to reduce number of traversed node
BinaryTree2DoubleLinkedList(root.getRight(), tempHead);
}
Other helper Details :
Initial call :
BinaryTree2DoubleLinkedList(bst.root,tempHead); //root and null value
Traverse List
printList(orgHead); //pass original head to print function
Complexity :
Time = Space : O(n)
public void ConverttoList(Node root){
Node top = root;
top.left = GetLeftNode(top.left);
top.right = GetRightNode(top.right);
top.left.right= top;
top.right.left= top;
Node leftmost = top.left;
while(leftmost.left!=null){
leftmost = leftmost.left;
}
while(leftmost!= null) {
System.out.printf(leftmost.Data + "->");
leftmost = leftmost.right;
}
}
public Node GetLeftNode(Node root){
if(root.left == null){
return root;
}
else{
Node startnode = GetLeftNode(root.left);
startnode.right = root;
root.left = startnode;
root.right = GetRightNode(root.right);
root.right.left = root;
Node rightmost=root.right;
while (rightmost.right!=null){
rightmost=rightmost.right;
}
return rightmost;
}
}
public Node GetRightNode(Node root){
if(root.left == null){
return root;
}
else{
Node startnode = GetLeftNode(root.left);
startnode.right = root;
root.left = startnode;
root.right = GetRightNode(root.right);
root.right.left = root;
Node leftmost=root.left;
while (leftmost.left!=null){
leftmost=leftmost.left;
}
return leftmost;
}
}
// bst to dll will generate a sorted dll
public class TreeToDLL {
public static void main(String args[]){
TreeNode t = new TreeNode(5);
TreeNode t3 = new TreeNode(3);
TreeNode t1 = new TreeNode(1);
TreeNode t7 = new TreeNode(7);
TreeNode t9 = new TreeNode(9);
TreeNode t8 = new TreeNode(8);
t.setLeft(t3);
t3.setLeft(t1);
t.setRight(t7);
t7.setRight(t9);
t9.setLeft(t8);
DllNode dll = convert(t);
dll.print();
}
static class DllNode{
int data;
DllNode next;
DllNode prev;
public DllNode(int data) {
this.data = data;
}
public DllNode() {
}
public int getData() {
return data;
}
public DllNode getPrev() {
return prev;
}
public void setPrev(DllNode prev) {
this.prev = prev;
}
public void setData(int data) {
this.data = data;
}
public DllNode getNext() {
return next;
}
public void setNext(DllNode next) {
this.next = next;
}
public void print(){
DllNode t = this;
while(t!=null){
System.out.print(t.getData()+"->");
t = t.getNext();
}
}
}
static class TreeNode{
int data;
TreeNode left;
TreeNode right;
public TreeNode(int data) {
this.data = data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public TreeNode getLeft() {
return left;
}
public TreeNode setLeft(TreeNode left) {
this.left = left;
return this;
}
public TreeNode getRight() {
return right;
}
public TreeNode setRight(TreeNode right) {
this.right = right;
return this;
}
}
private static DllNode convert(TreeNode t){
DllNode d =convert(t,new PreviousDLLNode());
while(d.prev!=null){
d = d.prev;
}
return d;
}
private static DllNode convert(TreeNode t, PreviousDLLNode d){
if(t==null) return null;
convert(t.getLeft(),d);
DllNode dn = new DllNode(t.getData());
if(d.val!=null){
d.val.setNext(dn);
}
dn.setPrev(d.val);
d.val = dn;
convert(t.getRight(),d);
return dn; // this node will be in the middle of the dll.
}
private static class PreviousDLLNode{
DllNode val;
}
}
I solved my problem inserting treenodes sorted in order in a DLL like that:
I added in my netBeans package the DoubleLinkedList and BinarySearchTree classes needed (including the TreeNode and the DoubleNode etc) and
I modified the BinarySearchTree as shown below:
public class BinarySearchTree {
DoubleLinkedList dL;
TreeNode root;
public BinarySearchTree() {
this.root = null;
this.dL=new DoubleLinkedList();
}
public void
tree2DList(TreeNode TN) {
if (TN == null) {
return ;
} else {
tree2DList(TN.left);
dL.insertLast((YourClassOfObjects)TN.getItem());
tree2DList(TN.right);
}
return;
}
I added a DoubleLinkedList field which I initialized in the default constructor of BST, calling the default constructor of DLL and I created the recursive method below, inspired from and following inOrderTraversal for the sorted input of tree nodes in the DLL
I've been trying to create a integer binary search tree with Java and for some reason, I've been going wrong with adding new nodes to the tree.
Here is the NODE class.
class NODE
{
NODE left = null, right = null;
int info;
public NODE(int x)
{
info = x;
}
}
and here's the BST(Binary Seatch Tree) class with the insert() method.
class BST
{
NODE tree = null;
public void insert(int x)
{
NODE node = new NODE(x);
NODE temp = tree;
while(true)
{
if(temp == null)
{
temp = node;
break;
}
else if(temp.info > x) temp = temp.left;
else temp = temp.right;
}
}
//other methods present here
}
For reasons that I could not figure out, the insert() method is going wrong.
The object tree carries null in it even after the insert() method is called.
Can you find something spotty in the code?
Thanks!
Use a recursive insert method in the NODE class (instead of utilizing an infinite loop as you did):
public void insert(int x) {
if(x < this.info) {
if(this.left == null)
this.left = new NODE(x);
else
this.left.insert(x);
}
else {
if(this.right == null)
this.right = new NODE(x);
else
this.right.insert(x);
}
}
And your BST class would have the following insert method (simply calls the other insert method):
public void insert(int x) {
if(tree == null)
tree = new NODE(x);
else
tree.insert(x);
}
The main insert method is in the NODE class because it must recursively call itself on nodes within the tree.
Of course tree remains null - you don't assign anything to this field.
After temp = tree; and temp = node; only temp is changed, not tree.
The insert() method should insert the child of a node into the tree, calling an already declared Node as a parameter. e.g.:
//Returns true/false depending on whether the insert is successful
public boolean insert(int x, Node node, boolean leftChild) {
if (node == null) return false;
Node child = new Node(x);
if (leftChild) {
if (node.left != null) return false;
node.left = child;
} else {
if (node.right != null) return false;
node.right = child;
}
return true;
}
So this is my first java program, but I've done c++ for a few years. I wrote what I think should work, but in fact it does not. So I had a stipulation of having to write a method for this call:
tree.insertNode(value);
where value is an int.
I wanted to write it recursively, for obvious reasons, so I had to do a work around:
public void insertNode(int key) {
Node temp = new Node(key);
if(root == null) root = temp;
else insertNode(temp);
}
public void insertNode(Node temp) {
if(root == null)
root = temp;
else if(temp.getKey() <= root.getKey())
insertNode(root.getLeft());
else insertNode(root.getRight());
}
Thanks for any advice.
// In java it is little trickier as objects are passed by copy.
// PF my answer below.
// public calling method
public void insertNode(int key) {
root = insertNode(root, new Node(key));
}
// private recursive call
private Node insertNode(Node currentParent, Node newNode) {
if (currentParent == null) {
return newNode;
} else if (newNode.key > currentParent.key) {
currentParent.right = insertNode(currentParent.right, newNode);
} else if (newNode.key < currentParent.key) {
currentParent.left = insertNode(currentParent.left, newNode);
}
return currentParent;
}
Sameer Sukumaran
The code looks a little confusing with overloaded functions. Assuming member variables 'left' and 'right' to be the left child and right child of the BSTree respectively, you can try implementing it in the following way:
public void insert(Node node, int value) {
if (value < node.value)
{
if (node.left != null)
{
insert(node.left, value);
}
else
{
node.left = new Node(value);
}
}
else if (value > node.value)
{
if (node.right != null)
{
insert(node.right, value);
}
else
{
node.right = new Node(value);
}
}
}
........
public static void main(String [] args)
{
BSTree bt = new BSTree();
Node root = new Node(100);
bt.insert(root, 50);
bt.insert(root, 150);
}
You should have a look to this article. It helps to implement a tree structure and search, insert methods:
http://quiz.geeksforgeeks.org/binary-search-tree-set-1-search-and-insertion/
// This method mainly calls insertRec()
void insert(int key) {
root = insertRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node insertRec(Node root, int key) {
/* If the tree is empty, return a new node */
if (root == null) {
root = new Node(key);
return root;
}
/* Otherwise, recur down the tree */
if (key < root.key)
root.left = insertRec(root.left, key);
else if (key > root.key)
root.right = insertRec(root.right, key);
/* return the (unchanged) node pointer */
return root;
}
You can use standard Integer (wrapper for primitive int) object instead of creating a new object type Node. On latest java Integer/int auto-boxing is supported. Hence your method insertNode(int key) can take in Integer argument too (ensure it is not null).
EDIT: Pls ignore above comment. I did not understand your real question. You will have to overload insertNode(). I think you are right.
but where is temp when you insertNode?? With your current implementation temp is lost if root is not null.
I think you want something like
root.getLeft().insertNode(temp);
and
root.getRight().insertNode(temp);
i.e. To insert the new Node (temp) to either the left or the right subtree.