Binary Tree- How to delete elements; java - java

node root=null;
public node delete(node node, int val) {
if(node == null) {
return node;
}
if(val < node.value) {
node.left= delete(node.left, val);
} else if(val > node.value) {
node.right= delete(node.right, val);
} else {
if(node.left== null || node.right== null) {
node temp = node.left!= null ? node.left: node.right;
if(temp == null) {
return null;
} else {
return temp;
}
} else {
node next = getSuccessor(node);
node.value= next.value;
node.right= delete(node.right, next.value);
return node;
}
}
return node;
}
public node getSuccessor(node node) {
if(node == null) {
return null;
}
node temp = node.right;
while(temp.left!= null) {
temp = temp.left;
}
return temp;
}
this is my code
and this is the class for the nodes:
public class node {
int value;
node left;
node right;
}
I already have a working code to add values.
the problem is, when i add values, and try to delete some of them with the code i just wrote here, it's not working.
this is what i put in main class when i try to delete a value:
binarytree tree= new binarytree;
node root=null;
root=tree.delete(root,4);
does anyone have any idea what could be wrong?
am i missing a function that refers to the delete one or something like that?
please note i'm new to java so if you want to help me treat me as a beginner
i'd really appreciate if someone could help me make my delete function work because now it's not doing anything at all...
EDIT:
Code to add values:
void recadd(node a, int val) {
if (val<a.value) {
if (a.left==null){
a.left=new node (val);
}
}
else
{
if(a.right==null) {
a.right=new node(val);
}
else {
recadd(a.right, val);
}
}
}
the code i use to call the add function:
void add(int val){
node k = new node (val);
if (root==null)
{
root = k;
}
else
{
recadd(root, val);
}
}
as stated before, i can add values just fine, the problem occurs when i try to delete them.

Your code should work. Maybe something is wrong with how you are inserting elements. Can you please share your full code?

Related

Couldn't insert values in BinaryTree [duplicate]

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

Binary Tree Traversal not showing full list

so currently I’m trying to follow a tutorial from FreeCodeCamp on implementing a Binary tree, but I’m having trouble with adding to and traversing through my tree.
For some reason, it seems that I’m able to add nodes to my tree, but when I try to traverse through my tree via iterative preorder traversal, it only picks up my root node. Its as if my nodes aren’t pointing to each other.
I have a feeling that the problem either lies with my add method or my traversal method, both of which are below. Any help would be greatly appreciated.
Add method:
public boolean add(T thing)
{
if(contains(thing))
{
return false;
} else {
root = add(root,thing);
count++;
return true;
}
}
private Node add(Node node,T thing)
{
if(node == null)
{
node = new Node(thing,null,null);
} else
{
if(thing.compareTo(node.value) <0)
{
if(node.left == null)
{
node.left = node = new Node(thing,null,null);
} else{
node.left =add(node.left,thing);
}
}
else
{
if(node.right == null)
{
node.right = node = new Node(thing,null,null);
}else {
node.right = add(node.right,thing);
}
}
}
return node;
}
Traversal:
public void traverse()
{
preorder(root);
}
private void preorder(Node node)
{ int iteration=0;
java.util.Stack<Node> stack = new java.util.Stack<Node>();
System.out.println( "root is: " +node.value);
stack.push(node);
while(stack.empty() == false)
{
Node current = stack.pop();
System.out.println("in preorder: "+current.value);
if(current.right != null)
{
stack.push(current.right);
}
if(current.left != null)
{
stack.push(current.left);
}
iteration++;
}
System.out.println("iteration: "+iteration);
}
You are not traversing your tree while adding in the tree. Check my tree insert method to get the idea:-
void insert(Node temp,int value) {
if(temp==null){
temp=new Node(value,null,null);
this.root=temp;
}
else{
Queue<Node> q = new LinkedList<>();
q.add(temp);
while (!q.isEmpty()) {
temp = q.peek();
q.remove();
if (temp.left == null) {
temp.left = new Node(value, null, null);
break;
} else
q.add(temp.left);
if (temp.right == null) {
temp.right =new Node(value, null, null);
break;
} else
q.add(temp.right);
}
}
}

How to print out a linkedlist?

Can somebody help me fix this issue with the code that I wrote?
When I run it doesn't print out the values of the linked list. I don't understand what is the problem, the compiler keeps giving a blank screen when I run the code.
public class Node {
int data;
Node next;
public static void main (String Args [])
{
Link object = new Link ();
object.insert(15);
object.insert(30);
object.insert(50);
object.insert(70);
object.show();
}
}
public class Link {
Node head;
void insert (int data)
{
Node node = new Node();
node.data=data;
if (head == null)
{
node=head;
}
else
{
Node n = head;
while (n.next != null)
{
n=n.next;
}
n.next=node;
}
}
void show ()
{
Node n = head;
while (n != null)
{
System.out.println(n.data);
n=n.next;
}
}
}
Your code is doing this:
if (head == null)
{
node=head;
}
This sets the null in head into the variable node. You aren't setting the value of head.
You should be doing this (setting the value of node into the variable head):
if (head == null)
{
head = node;
}
In your Link class, you need to change the following:
if (head == null)
{
node=head; //<-- change this to head = node;
}
¿Do you have to do it by that way? Java has already a LinkedList utility, makes it easier.

Tree addNode detect the root

I am creating a tree and learning TDD. I am not sure how I can detect the root here while adding node. Essentially I want 1 -> 2 -> 3 formed. I think thats how it would look in memory with my current setup. Obviously below test fails. (partly)
Test code:
#Test
public void test() {
Nodes root = new Nodes(4);
assertNotNull(root);
root.addNode(5);
root.addNode(6);
assertEquals(5, root.printNodes(root)[1]);
assertEquals(6, root.printNodes(root)[2]);
}
When I am adding a node, I want to add it to the root.
public class Nodes {
int data;
Nodes next;
Nodes(int data) {
this.data = data;
}
public void addNode(int i) {
Nodes newNode = new Nodes(i);
while (newNode.next != null) {
//detect root and add the newnode
}
}
public int[] printNodes(Nodes root) {
int[] n = new int[5];
int i = 0;
while (root != null) {
n[i] = root.data;
root = root.next;
i++;
}
return n;
}
}
root.addNode(5);
root.addNode(6);
With your current code, you don't need to detect what the root node is (you already have it with root), you need, instead, to detect the order of inserted nodes.
So your addNode could be something like the following:
public void addNode(int i)
{
if (i == this.data) {
// what do you do when data equal?
} else {
if (this.next != null) {
if (this.next.data < i) {
this.next.next = new Nodes(i);
} else {
Nodes tmp = new Nodes(i);
tmp.next = this.next;
this.next = tmp;
}
} else {
this.next = new Nodes(i);
}
}
}
And then your printNodes function:
public void printNodes()
{
Nodes tmp = this;
while (tmp != null) {
System.out.printf("%d\n", tmp.data);
tmp = tmp.next;
}
}
This implementation is, of course, not a binary tree, but you've stated you are wanting to start with this implementation and expand from there, so I hope this can help you get there.

circular single linkedList

I've done some exercises in Java and now I'm stuck at such a problem - my list works incorrectly. I am sure that remove works incorrectly and maybe you can help me (with advice or code) to implement a circular singly linked list in a correct way. I am not sure whether other functions work properly, but I've tried to do my best.
Here is my code:
import java.util.*;
public class Node {
private Object value;
private Object nextValue;
private Node next;
public Node(int data) {
this.value = data;
this.next = null;
}
public Object getValue() {
return this.value;
}
public Node nextItem() {
return this.next;
}
public void setNextItem(Node nextItem) {
this.next = (Node) nextItem;
this.next.setValue(nextItem.getValue());
}
public void setValue(Object arg0) {
this.value = arg0;
}
}
-------------------------------------------------------------------
import java.util.*;
public class CircularList {
private Object[] array;
private int arrSize;
private int index;
private Node head;
private Node tail;
public CircularList() {
head = null;
tail = null;
}
public boolean add(Node item) {
if (item == null) {
throw new NullPointerException("the item is null!!!");
}
if (head == null) {
head = item;
head.setNextItem(head);
arrSize++;
return true;
}
Node cur = head;
while(cur.nextItem() != head) {
if(cur.getValue() == item.getValue()) {
throw new IllegalArgumentException("the element already " +
"exists!");
}
cur = cur.nextItem();
}
head.setNextItem(item);
item.setNextItem(head);
arrSize++;
return true;
}
public Node getFirst() {
return head;
}
public void insertAfter(Node item, Node nextItem) {
if ((item == null) || (nextItem == null)) {
throw new NullPointerException("the item is nul!!!");
} else if (this.contains(nextItem) == true) {
throw new IllegalArgumentException("the item already exists!");
}
Node cur = head;
while(cur.nextItem() != head) {
if(cur.getValue() == item.getValue()) {
nextItem.setNextItem(item.nextItem());
item.setNextItem(nextItem);
} else {
cur = cur.nextItem();
}
}
}
public boolean remove(Node item) {
if(item == head) {
Node cur = head;
for(int i = 0; i < arrSize-1; i++) {
cur = cur.nextItem();
}
head = head.nextItem();
for(int i = 0; i < arrSize; i++) {
cur = cur.nextItem();
}
arrSize--;
return true;
}
Node cur = head;
int counter = 0;
while(cur.nextItem() != head) {
if(cur == item) {
item = null;
cur = cur.nextItem();
while(cur.nextItem() != head) {
cur.setNextItem(cur.nextItem().nextItem());
}
return true;
}
cur = cur.nextItem();
}
return false;
}
public int size() {
return arrSize;
}
public boolean contains(Object o) {
if ((o == null) && (arrSize == 0)) {
return false;
}
Node cur = head;
while(cur.nextItem() != head) {
if(cur.getValue() == o) {
return true;
}
cur = cur.nextItem();
}
return false;
}
}
Many of these algorithms could be simpler.
Example:
public boolean remove(Node item) {
Node current = head;
for(int i = 0; i < size; i++) {
if (current.getNext() == item) {
current.next = current.getNext().getNext();
size --;
return true;
}
current = current.getNext()
}
return false;
}
There are a variety of issues here beyond the list. You seem to be comparing your nodes with ==. This code will output 'no match'.
Node n1 = new Node(5);
Node n2 = new Node(5);
if (n1 == n2)
System.out.println("objects match");
else
System.out.println("no match");
In add(), it looks like you can only ever have two items in the list, so
head.setNextItem(item);
item.setNextItem(head);
should be this:
cur.setNextItem(item);
item.setNextItem(head);
There's a lot going on in your code, here's some advice for some of it:
In your Node class: Java naming conventions: the same way that setters should be prefixed with "set," getters should be prefixed with "get:" nextItem() should really be getNextItem().
Also in your Node class: as far as I know, the "next value" field of a node of a linked list is usually a reference to the next Node in the list, and should therefore be of type Node, not just any Object. It should work the way you have it, but using explicit typing is a lot safer. (Please correct me if using "Object" is indeed a common way to construct the next node of a linked list.)
In the first case of remove(), when removing the head: you're looping through the list to reach the last value, presumably to reset its "next value" to the new head, but you're not actually doing it. You want something like this:
if (item == head) {
head = head.nextItem();
for(int i = 0; i < arrSize-1; i++){
cur = cur.nextItem();
}
}
cur.setNextItem(head);
I'm not sure what you hope to accomplish with the second loop.
In the second case of remove(): I'm not sure what you're trying to do with the second while loop - reset all the links in the whole list? The whole point of a linked list is to make that unnecessary. Deleting a node in a linked list does not actually get rid of the object (so you don't have to set item to null). Rather, you simply "go around" the unwanted object and "ignore" it, effectively removing it from the list, as in:
Original list:
[ Value: A; Next: B ] --> [ Value: B; Next: C ] --> [ Value C; Next: D ] ...
After deleting node B:
[ Value: A; Next: C ] --> [Value C; Next: D ] ...
[ Value: B; Next: C ] still exists in memory, but nothing is pointing to it, so it will be removed in the next garbage collection cycle.
To implelement: As you walk the list, keep a reference to the previous node that you visited. Then, once you find the item you're looking for (using correct comparison, as Thomas noted), you can simply set prev.setNextItem(cur.nextItem()); (caveat: untested code):
Node prev = head;
Node cur;
while ((cur = prev.nextItem()) != head) {
if (cur.equals(item)) {
prev.setNextItem(cur.getNextItem());
return true;
}
}
I hope these tips help you along the correct path.

Categories