I am having issue in understanding the following code. It is a tree data structure and I don't understand why do we need two node (parent and focusnode) in the addnode() method. I tried to do it with just focusnodebut it doesn't work out. My idea is set focusnode to root, and keep looping it until focusnode is equal to null, and set focusnode to newnode.
public class tree {
node root;
public class node{
private int key;
private node left;
private node right;
node(int key){
this.key = key;
}
public int getkey(){
return key;
}
public node getleft(){
return left;
}
public node getright(){
return right;
}
}
public void addnode(int key){
node newnode = new node(key);
if(root == null){
root = newnode;
}else{
node focusnode = root;
node parent;
while(true){
parent = focusnode;
if(key < focusnode.key){
focusnode = focusnode.left;
if(focusnode == null){
parent.left = newnode;
return;
}
}else{
focusnode = focusnode.right;
if(focusnode == null){
parent.right = newnode;
return;
}
}
}
}
}
public void runnode(node focusnode){
if(focusnode != null){
runnode(focusnode.left);
runnode(focusnode.right);
System.out.println(focusnode.key);
}
}`
If you are doing the check like this:
if(key < focusnode.key){
focusnode = focusnode.left;
if(focusnode == null){
focusnode = newnode;
return;
}
}
}
You are looping until focusnode is null, then creating a new node, but not attaching it to the the parent node. As a result, when you try to loop again, you can't loop past the root node since it has no children! If you wish to avoid dealing with the parent node variable, you need to check the child in the condition before setting focusnode, and only set focusnode if the child is not null. e.g:
if(key < focusnode.key){
if(focusnode.left == null){
focusnode.left = newnode;
return;
} else {
foucusnode = focusnode.left;
}
}
}
The check is the same for the right side.
Because if you need to assign a new node as parent's .left or .right child (which happens after you find that focusnode == null... meaning .left/.right is null), then you need a reference to that .left/.right child (the reference is from the parent). You can't set focusnode to your newnode, because it will only assign your newnode to focusnode and not toparent.rightorparent.left`.
So you'll set the focusnode reference to your newnode, but the parent's .left/.right child nodes will not reference your newnode.
If you're coming from C/C++ or similar, imagine that all of these variables are pointers. *focusnode is pointing towards the same object that *parent.left is pointing to. Making *focusnode point to a different object will not change what *parent.left is pointing to.
All variables in Java are references (aside from primitives like int/double etc), which are similar to pointers in C/C++.
Related
I am having trouble figuring out how to set a variable "minData" to the minimum value inserted into a binary search tree. If I am thinking of this correctly, the most minimum value in the tree will always be in the left subtree so my code for setting this minimum value should go under the "else if (root.data < data)" statement. I also don't know how to access the minData variable inside my insert method. My code so far is:
private class Node {
int key;
int data;
int minData;
private Node left;
private Node right;
private Node root;
Node(int data) {
this.data = data;
left = null;
right = null;
root = null;
}
}
public TheBST(Node root) {
root = null;
}
public void insert(Node root, int data) {
Node newNode = new Node(data);
if(root == null) {
Node node = new Node(data);
root = node;
}
else if(root.data > data) {
if(root.left == null) {
Node node = new Node(data);
root.left = node;
}
insert(root.left, data);
}
else if(root.data < data) {
if(root.right == null) {
Node node = new Node(data);
root.right = node;
return;
}
insert(root.right, data);
}
}
Your forming of BST is not accurately done. You need to return from the method (or stack fragment of memory in case recursive procedure) when you would actually find the place to insert.
Add the return statement for the left-subtree:
else if(root.data > data) {
if(root.left == null) {
Node node = new Node(data);
root.left = node;
return;
}
insert(root.left, data);
}
Which is you are doing in case of the right-subtree.
P.S: once you are done with tree insertion, you can return the left-most-node from left-subtree, it would have the minimum value.
I have a binary tree like the picture below, I want to implement a method called findNode to return the node holding the value entered as a parameter.
For example: findNode(8)=8, findNode(13)=13.
I tried to modify this code but it didn't working :
class Node {
Node left, right;
int value;
public Node findNode(int value) {
Node focusNode = root;
if (focusNode == null) {
return null;
}
while (focusNode.value != value) {
// If we should search to the left
if (value < focusNode.value) {
// Shift the focus Node to the left child
focusNode = focusNode.left;
} else {
// Shift the focus Node to the right child
focusNode = focusNode.right;
}
return focusNode;
}
}
}
See if this helps. You can't default to left or right but need to check them explicitly. The null situation is taken care of by the while loop.
public Node findNode(int value) {
Node focusNode = root;
while (focusNode != null) {
// If we should search to the left
if (value < focusNode.value) {
// Shift the focus Node to the left child
focusNode = focusNode.left;
} else if (value > focusNode.value) {
// Shift the focus Node to the right child
focusNode = focusNode.right;
} else {
// Found!!
return focusNode;
}
}
return null;
}
Here's a cleaner approach:
class Node {
Node left, right;
int value;
public static Node findNode(Node current, int value) {
if (current == null)
return null;
if (current.value == value)
return current;
if (current.value < value)
return findNode(current.left, value);
else
return findNode(current.right, value);
}
}
your root is either not defined or null every time.
below code would work as expected.
class Node
{
int value;
Node left, right;
public Node(int item)
{
value = item;
left = right = null;
}
}
public class BinaryTree {
Node root;
public Node findNode(int value) {
Node focusNode = root;
if (focusNode == null){
return null;
}
while (focusNode.value!= value) {
// If we should search to the left
if (value< focusNode.value) {
// Shift the focus Node to the left child
focusNode = focusNode.left;
} else {
// Shift the focus Node to the right child
focusNode = focusNode.right;
}
}
return focusNode;
}
My code for inserting a node into a BST is not working. When I try to display it shows only the last two nodes of the tree, i.e. it somehow overwrites the nodes in a tree. What did I do wrong? Thanks in advance!
public Node Insert(int value)
{
Node newNode = new Node();
newNode.data = value;
newNode.left = null;
newNode.right = null;
if(root == null){
root = newNode;
return root;
}
else{
while(root != null){
if(root.data < value){
if(root.right != null){
root = root.right;
}
else{
root.right = newNode;
break;
}
}
else{
if(root.left != null){
root = root.left;
}
else{
root.left = newNode;
break;
}
}
}
return root;
}
}
public void inOrder(){
inOrder(this.root);
}
private void inOrder(Node root){
if(root != null){
inOrder(root.left);
System.out.println(root.data);
inOrder(root.right);
}
}
root points to the top node of your tree. In the while you are changing its value. You must use anoter variable (say 'n').
The initial value of 'n' is 'root'.
And inside the while you only use 'n'.
if(root == null){
root = newNode;
return root;
}
else{
Node n = root;
while(n != null){
...
}
return root;
...
You must return 'root', not 'n', because the root don't change.
See my comments in the code . Hope it helps.
public Node Insert(int value)
{
Node newNode = new Node();
newNode.data = value;
newNode.left = null;
newNode.right = null;
if(root == null){
root = newNode;
return root;
}
else{
while(root != null){
if(root.data < value){
if(root.right != null){
root = root.right;
// root should point to the head of the tree.
/* Here you are changing the variable root to point to some other memory location and the reference to the head of the tree is lost. You should store the reference to the head of the tree in a temporary variable to return later */
}
else{
root.right = newNode;
break;
}
}
else{
if(root.left != null){
root = root.left;
//root should point to the head of the tree.
/* Here you are changing the variable root to point to some other memory location and the reference to the head of the tree is lost. You should store the reference to the head of the tree in a temporary variable to return later */
}
else{
root.left = newNode;
break;
}
}
}
// return temporary variable which points to the head of the tree here
return root;
}
}
public void inOrder(){
inOrder(this.root);
}
private void inOrder(Node root){
if(root != null){
inOrder(root.left);
System.out.println(root.data);
inOrder(root.right);
}
}
I am trying to insert node in a binary tree using recursive method. But once its out of the method the root becomes the new node and left child and right child are null. With this I'm trying to learn how recursion works. Also, does recursive method always has to return something. Below is the code.
public class BinaryNode {
int key;
BinaryNode left;
BinaryNode right;
public BinaryNode( int key){
this.key = key;
// this.left = left;
//this.right = right;
}
}
public class BinaryTree {
BinaryNode root;
public void insert(int key){
BinaryNode newNode = new BinaryNode(key);
if(root == null){
root = newNode;
}else{
BinaryNode focusNode = root;
BinaryNode parent;
while(true){
parent = focusNode;
if(key<focusNode.key){
focusNode = focusNode.left;
if(focusNode==null){
parent.left= newNode;
return;
}
}else{
focusNode = focusNode.right;
if(focusNode==null){
parent.right= newNode;
return;
}
}
}
}
}
public BinaryNode recursiveInsert(int key, BinaryNode node){
BinaryNode newNode = new BinaryNode(key);
if (node == null){
root = newNode;
}
else{
if(key < node.key){
root.left = recursiveInsert(key, node.left);
}
else{
root.right = recursiveInsert(key, node.right);
}
}
return root;
}
public String toString(){
String toTree = null;
return toTree;
}
public static void main(String[]args){
BinaryTree tree = new BinaryTree();
tree.recursiveInsert(7, tree.root);
tree.recursiveInsert(6, tree.root);
tree.recursiveInsert(4, tree.root);
tree.recursiveInsert(8, tree.root);
tree.recursiveInsert(9, tree.root);
tree.recursiveInsert(5, tree.root);
}
}
The method I'm trying is recursiveInsert. Thanks!!
I suppose the problem comes from
if (node == null){
root = newNode;
}
You are traversing the tree and in the last step you are asking the left/right child of a leaf node. This hasn't one, so it's child is null.
This is the value returned by the recursive calls and in the end, it gets assigned to root.
To fix this, before descending into a node, make sure that child node exists.
Also this is a bit weird
root.left = recursiveInsert(key, node.left);
It should be node and not root.
There are several issues with your code which I won't necessarily go into, because I think they distract from your core questions.
To answer your second question first: No, there's no rule that says that recursive methods have to return anything. It's more important that they know when to terminate.
As for your bug, I think it's probably due to the fact that your insert method always returns and operates on root. You probably mean to modify and return newNode.
This is because your recursiveInsert method always operates on root. Try this instead -
public Node recursiveInsert(Node currentParent, Node newNode) {
if (currentParent == null) {
return newNode;
} else if (newNode.key > currentParent.key) {
currentParent.right = recursiveInsert(currentParent.right, newNode);
} else if (newNode.key < currentParent.key) {
currentParent.left = recursiveInsert(currentParent.left, newNode);
}
return currentParent;
}
Your recursive code should be like this :
public BinaryNode recursiveInsert(int key, BinaryNode node) {
if (node == null) {
return root = new BinaryNode<>(key);
} else {
if (key < node.key) {
if (node.left == null) {
return node.left = newNode;
} else {
return recursiveInsert(key, node.left);
}
} else {
if (node.right == null) {
return node.right = newNode;
} else {
return recursiveInsert(key, node.right);
}
}
}
}
You are acting on root node in your recursive function, you should rather be acting on the node passed to the recursive function.
I'm working on code for insertion into a binary search tree. It works for the first node I insert, making it the root, but after that it doesn't seem to insert any nodes. I'm sure it's a problem with setting left/right references, but I can't quite figure it out. Please help!
//params: key of node to be inserted, parent node
public void insert(int newKey, TreeNode parent){
//if the root of the tree is empty, insert at root
if(this.getRoot() == null){
this.root = new TreeNode(newKey, null, null);
}
//if the node is null, insert at this node
else if(parent == null)
parent = new TreeNode(newKey, null, null);
else{
//if the value is less than the value of the current node, call insert on the node's left child
if(newKey < parent.getKey()) {
insert(newKey, parent.getLeft());
}
//greater than value of current node, call insert on node's right child
else if(newKey > parent.getKey()){
insert(newKey, parent.getRight());
}
//same as value of current node, increment iteration field by one
else if(newKey == parent.getKey())
parent.incrementIterations();
}
}
My treenodes have key, left, right, and iteration fields, as well as getter/setter functions.
Thank you in advance!
public Node insertNode(Node head, int data) {
if(head == null){
head = new Node();
head.data = data;
return head;
}
if(head.data < data) {
head.right = insertNode(head.right,data);
} else {
head.left = insertNode(head.left, data);
}
return head;
}
If (parent==null) you are creating a node, but you are not associating it to tree back. Its just created and garbage collected.
You should be using insert (newkey, parent) then u still have handle to tree
private AVLNode insert(AVLNode root, int value){
if (root == null) return new AVLNode(value);
if(root.value > value)
root.leftChild = insert(root.rightChild, value);
else
root.rightChild = insert(root.leftChild, value);
return root;
}