Implementing a linked list in Java (Finding/Deleting Nodes) - java

I've been working on some code to implement an (edit: unidirectional) linked list in java. My main issue is coming about when it comes to finding and deleting nodes, that is, using Find(data) tells the user whether or not a node is present in the list; Delete(data) actually removes the node from the list after it is found (or does nothing if the node isn't found). Find(data) and Delete(data) use the same if-else logic, so for right now I just copied the code from the Find method into the delete method, with appropriate pointers in the delete method to "hop over" the deleted node.
I'm wondering if there's a more efficient way of doing this. I thought of using booleans in the delete block, for example:
public void Delete(data)
{
if Find(data)
{
//code to delete node
}
}
but because the current node could be at the head, tail, or somewhere in the middle, you'd still have to have the loop logic to check where you are so you can set the appropriate references. For example, if the user wants to delete the node at the tail, then the previous node's next node would be set to null. However, in the middle, you'd have to run a while loop to iterate through the list, i.e.
while (iter.NextNode !=null)
{
if (iter.NextNode.data == data)
{
iter.NextNode = iter.NextNode.NextNode;
System.out.println(data + " was found in the list and removed"
break;
}
else if (iter.NextNode.NextNode == null && iter.NextNode.data == data)
{//this is kinda weird. I couldn't use an else block, because either
//the code would never exit the loop, or it would keep running
iter.NextNode = null;
System.out.println(data + " was found in the list and removed. ");
break;
}
iter = iter.NextNode;
if (node.NextNode == null && node.data != data)
{//i guess I could have just put this if statement inside
//the else block
System.out.println(data + " was not found in the list.");
break;
}
}
The above code block handles both cases.
The below code block is my Find(data) method:
public void Find(int data)
{
Node node = head;
if (head == null)
{
System.out.println("No nodes found. ");
}
else if (node.NextNode==null)
{
if (node.data == data)
{
System.out.println( data + " was found in the list.");
}
else
{
System.out.println("That value was not found in the list.");
}
}
else
{
while (node.NextNode !=null)
{
if (node.data == data)
{
System.out.println(data + " was found in the list.");
break;
}
else if (node.NextNode.NextNode == null && node.NextNode.data == data)
{
System.out.println(data + " was found in the list.");
break;
}
else
{
node = node.NextNode;
}
if (node.NextNode == null && node.data != data)
{
System.out.println(data + " was not found in the list.");
break;
}
}
}
}
In case the question wasn't clear: Is there a way I can use my Find(data) method in the delete block, and take out all the logic?
Thanks for your guidance. I really appreciate it!

As your Find() method returns nothing, you can not use it in a Delete() method.
To Centralize your code for Find() and Delete() create another private method - getPreviousNode(int data) which returns previous node of a required node.
private Node getPreviousNode(int data) {
Node iter = head;
while (iter.NextNode != null) {
if (iter.NextNode.data == data) {
return iter;
}
iter.nextNode = iter.nextNode.nextNode;
}
return null;
}
Call this method in both Find() and Delete() method.
void Find(int data) {
// Code to handle head & tail conditions
Node prevNode = getPreviousNode(data);
if (prevNode != null) {
System.out.println("Found");
}
...
}
void Delete(int data) {
// Code to handle head & tail conditions
Node prevNode = getPreviousNode(data);
if (prevNode != null) {
Node node = prevNode.nextNode;
prevNode.nextNode = node.nextNode;
node.nextNode = null;
System.out.println("Found & Deleted");
}
...
}
Answer to your comment:
Writing just "prevNode.nextNode = prevNode.NextNode.NextNode" is not sufficient.
Consider Following LinkedList:
A[data = 1 | nextNode = b] --> B[data = 4 | nextNode = c] --> C[data = 55 | nextNode = null]
where,
A, B, C : Nodes
a, b, c : References to Nodes A, B and C respectively.
B : Node to delete
Now consider a code to delete node:
Node prevNode = getPreviousNode(data);
prevNode = a; // "a" is a reference to Node A returned by getPreviousNode(4)
if (prevNode != null)
node = prevNode.nextNode;
node = b; // prevNode.nextNode is 'b'
prevNode.nextNode = node.nextNode;
prev.NextNode = c; // node.nextNode is 'c'
Now LinkedList is:
A[data = 1 | nextNode = c] B[data = 4 | nextNode = c] --> C[data = 55 | nextNode = null]
Now node A has a reference of Node C as a nextNode. So Node B is unlinked from LinkedList
but not completely removed from LinkedList because Node B is still having reference of Node C
as a NextNode. So you must remove this reference to remove Node B completely from LinkedList.
So following statement is neccessary
node.nextNode = null;
Now LinkedList is:
A[data = 1 | nextNode = c] --> C[data = 55 | nextNode = null]
B[data = 4 | nextNode = null] is removed from LinkedList.

You could share findPrevious as #SanjayChavan suggests, but when you are practiced at writing linked list code, you find that it's already clean and sharing findPrevious doesn't make it better:
boolean Delete(int data)
{
Node prev = null, node = null;
for (node = head; node!=null; node=(prev=node).nextNode)
{
if (node.data == data)
{
if (prev!=null)
prev.nextNode = node.nextNode;
else
head = node.nextNode;
node.nextNode = null;
return true;
}
}
return false;
}
Node Find(int data)
{
for (Node node = head; node != null; node = node.nextNode)
{
if (node.data==data)
return node;
}
return null;
}
Once Sanjay's code is fixed so that it can find and delete the head node, it will be longer and more complicated than this.

public static ListNode search( List list, int target )
{
ListNode cursor = list.getFirst( );
while( cursor != null )
{
if( cursor.getInfo( ) == target )
return cursor;
cursor = cursor.getLink( );
}
return cursor;
}
public void remove( int element )
{
ListNode cursor;
ListNode target = search( this, element );
if( isEmpty( ) )
System.out.println( "There are no elements in this list." );
if( target == null )
System.out.println( element+" is not in this list." );
else
{
if( head.getInfo( ) == element )
{
if( head.getLink( ) == null )
head = null;
else if( head == tail )
tail = null;
else
head = head.getLink( );
}
else if( tail.getInfo( ) == element )
{
for( cursor = head; cursor.getLink( ).getInfo( ) != element; cursor = cursor.getLink( ) )
{ }
cursor.setLink( null );
tail = cursor;
}
else
{
for( cursor = head; cursor.getLink( ).getInfo( ) != element; cursor = cursor.getLink( ) )
{ }
cursor.setLink( cursor.getLink( ).getLink( ) );
}
}
}

Related

How do I write an addElement method to a sorted LinkedList?

I have an assignment that goes:
implement a linked list of String objects by use of the class Node (see Big >Java Early Objects 16.1.1). Write methods, that make it possible to insert >and delete objects, as well as print all objects in the list. It is a >requirement that all elements in the list are sorted, at all times, according >to the natural ordering of Strings(Comparable).
The method that I can't seem to get right, is the addElement method
The entire class is here: https://pastebin.com/Swwn8ykZ
And the mainApp: https://pastebin.com/A22MFDQk
I've looked through the book (Big Java Early Objects), as well as looked on geeksforgeeks
public void addElement(String e) {
Node newNode = new Node();
if (first.data == null) {
first.data = e;
System.out.println("Success! " + e + " has been
added!");
} else if (first.data.compareTo(e) == 0) {
System.out.println("The element already exists in the
list");
} else {
while (first.next != null) {
if (first.next.data.compareTo(e) != 0) {
first.next.data = e;
} else {
first.next = first.next.next;
}
}
}
}
public static void main(String[] args) {
SortedLinkedList list = new SortedLinkedList();
String e1 = new String("albert");
String e2 = new String("david");
String e3 = new String("george");
String e4 = new String("jannick");
String e5 = new String("michael");
// ----------------SINGLE LIST--------------------------
list.addElement(e1);
list.addElement(e2);
list.addElement(e3);
list.addElement(e4);
list.addElement(e5);
System.out.println("Should print elements after this:");
list.udskrivElements();
}
}
Expected result: The five names printed in a list
Actual result: The first name printed
Given this Node class:
private class Node {
public String data;
public Node next;
}
and a class-level field of private Node first; that is initially null to signal an empty list,
the addElement could be like this:
public void addElement(String text) {
if (text == null) return; // don't store null values
Node extra = new Node();
extra.data = text;
if (first == null) {
// no list yet, so create first element
first = extra;
} else {
Node prev = null; // the "previous" node
Node curr = first; // the "current" node
while (curr != null && curr.data.compareTo(text) < 0) {
prev = curr;
curr = curr.next;
}
if (curr == null) {
// went past end of list, so append
prev.next = extra;
} else if (curr.data.compareTo(text) == 0) {
System.out.println("Already have a " + text);
} else {
// between prev and curr, or before the start
extra.next = curr;
if (prev != null) {
prev.next = extra;
} else {
// append before start, so 'first' changes
first = extra;
}
}
}
}
By the way, also try and add the names in an unsorted order to check that the list sorts them (I found a bug in my code when I tried that).

Insertion in sorted doubly linked list

I am given the pointer to the head node of a sorted doubly linked list and an integer to insert into the list.I am told to create a node and insert it into the appropriate position in the list such that its sorted order is maintained. The head node might be NULL.
Sample Input
NULL , data = 2
NULL <-- 2 <--> 4 <--> 6 --> NULL , data = 5
Sample Output
NULL <-- 2 --> NULL
NULL <-- 2 <--> 4 <--> 5 <--> 6 --> NULL
I tried the above problem.But My program is terminating due to timeout.What am I doing wrong in the below code. Assume Node class and main function is already there. Many Thanks in advance!!
Node SortedInsert(Node head,int data) {
Node newn = new Node();
newn.data = data;
newn.prev=null;
newn.next = null;
Node ptr = head;
Node nex=head.next;
while(ptr!=null && nex!=null) {
if(ptr.data<=newn.data && nex.data>=newn.data) {
newn.next = nex;
newn.prev = ptr;
nex.prev = newn;
ptr.next = newn;
}
else {
nex=nex.next;
ptr=ptr.next;
}
}
if(ptr!=null && nex==null) {
if(ptr.data>=newn.data) {
newn.next=ptr;
ptr.prev=newn;
newn.prev=null;
head=newn;
}
else {
ptr.next=newn;
newn.prev = head;
}
}
if(head==null) {
head = newn;
}
return head;
}
Fairly simple:
You are not breaking out of the loop after succesfully inserting. Therefore it keeps looping over the position it inserts the node in. Make a tiny change:
if(ptr.data>=newn.data)
{
newn.next=ptr;
ptr.prev=newn;
newn.prev=null;
head=newn;
break;
}
However, you have some redundant code written. This is shorter and doesn't contain redundant code:
Node SortedInsert(Node head,int data) {
Node newn = new Node();
newn.data = data;
Node ptr = head;
if (ptr == null) {
head = newn;
} else if ( ptr.data > newn.data ) {
newn.next = ptr;
ptr.prev = newn;
head = newn;
} else {
Node nex = head.next;
while (nex != null && nex.data <= newn.data) {
ptr = nex;
nex = nex.next;
}
ptr.next = newn;
newn.prev = ptr;
if (nex != null) {
nex.prev = newn;
newn.next = nex;
}
}
return head;
}
If the head node is null you'll geta NullPointerException while trying to get the next/prev nodes. You should check that first:
Node sortedInsert(Node head, int data) {
Node newn = new Node();
newn.data = data;
//Basic case: the list is empty, so the head is null
if (head==null) {
return newn;
}
//If node is not null
Node aux= head;
Node auxPrev;
while (aux!=null && aux.data<data) {
auxPrev=aux;
aux=aux.next;
}
//auxPrev will be null if we are going to insert in the first position
if (auxPrev!=null)
auxPrev.next=newn;
newn.prev=auxPrev;
head=newn;
}
//aux will be null if we insert in the last position
if (aux!=null) {
aux.prev=newn;
newn.next=aux;
}
return head;
}

Delete AnyType Linked List tail

I wrote A node class whose 'data' field is designed to hold any type of data and A linked list class designed to hold nodes with any type of data. I was implementing a class to delete duplicates ("deleteDuplicates") and found myself having trouble setting the tail to null ("deleting the tail") of my linked list and I feel like it's because I'm trying to set a class to null. What am I not understanding? I was hoping someone could correct my thinking. Specifically see my commented out code TODO on line 116 in the method deleteDuplicates.
import java.io.*;
// A node class whose 'data' field is designed to hold any type of data.
class node<AnyType> {
AnyType data;
node<AnyType> next;
// Constructor; sets this object's 'data' field to 'data'.
node(AnyType data) {
this.data = data;
}
}
// A linked list class designed to hold nodes with any type of data.
public class LinkedList<AnyType> {
// Notice that when you create a LinkedList object (in main(), for example),
// you tell it what kind of data it'll be holding. The LinkedList class
// needs to pass that information on to the node class, as well. That's
// what's happening here.
private node<AnyType> head, tail;
// insert at the tail of the list
void insert(AnyType data) {
// if the list is empty, set 'head' and 'tail' to the new node
if (head == null) {
head = tail = new node<AnyType>(data);
}
// otherwise, append the new node to the end of the list and move the
// tail reference forward
else {
tail.next = new node<AnyType>(data);
tail = tail.next;
}
}
// insert at the head of the list
void headInsert(AnyType data) {
// first, create the node to be inserted
node<AnyType> YouCanJustMakeANewNode = new node<AnyType>(data);
// insert it at the beginning of the list
YouCanJustMakeANewNode.next = head;
head = YouCanJustMakeANewNode;
// if the list was empty before adding this node, 'head' AND 'tail'
// need to reference this new node
if (tail == null)
tail = YouCanJustMakeANewNode;
}
// print the contents of the linked list
void printList() {
for (node<AnyType> temp = head; temp != null; temp = temp.next)
System.out.print(temp.data + " ");
System.out.println();
}
// Remove the head of the list (and return its 'data' value).
AnyType removeHead() {
// if the list is empty, signify that by returning null
if (head == null)
return null;
// Store the data from the head, then move the head reference forward.
// Java will take care of the memory management when it realizes there
// are no references to the old head anymore.
AnyType temp = head.data;
head = head.next;
// If the list is now empty (i.e., if the node we just removed was the
// only node in the list), update the tail reference, too!
if (head == null)
tail = null;
// Return the value from the old head node.
return temp;
}
node<AnyType> deleteNode(node<AnyType> data)
{
node<AnyType> helper = head;
if( helper.equals(data) )
{
return head.next;
}
while( helper.next != null )
{
if( helper.next.equals(data) )
{
helper.next = helper.next.next;
return helper;
}
helper = helper.next;
}
return helper;
}
void deleteDuplicates( LinkedList<Integer> L1 )
{
for (node<Integer> temp = L1.head; temp != null; temp = temp.next)
{
for (node<Integer> helper = temp; helper.next != null; helper = helper.next)
{
//start at helper.next so that temp doesn't delete it's self
if( temp.data == helper.next.data && helper.next.next != null )
{
helper.next = helper.next.next;
}
/* TODO: DELETE TAIL
//can't seem to figure out how to delete the tail
if( temp.data == helper.next.data && helper.next.next == null )
{
//helper.next = null;
}
*/
}
}
}
// returns true if the list is empty, false otherwise
boolean isEmpty() {
return (head == null);
}
public static void main(String [] args) {
// create a new linked list that holds integers
LinkedList<Integer> L1 = new LinkedList<Integer>();
/*
for (int i = 0; i < 10; i++)
{
// this inserts random values on the range [1, 100]
int SomeRandomJunk = (int)(Math.random() * 100) + 1;
System.out.println("Inserting " + SomeRandomJunk);
L1.insert(SomeRandomJunk);
}
*/
//8,24,15,15,9,9,25,9
L1.insert(8);
L1.insert(24);
L1.insert(15);
L1.insert(15);
L1.insert(9);
L1.insert(9);
L1.insert(25);
L1.insert(9);
//L1.insert(9);
//L1.insert(9);
// print the list to verify everything got in there correctly
System.out.println("Printing integer linked list");
L1.printList();
System.out.println("Printing DEL-repeaded LL");
L1.deleteDuplicates(L1);
L1.printList();
// create another linked list (this time, one that holds strings)
LinkedList<String> L2 = new LinkedList<String>();
L2.insert("Llamas");
L2.insert("eat");
L2.insert("very sexy");
L2.insert("critical thinking");
L2.insert("Paper clips annd now I'm ");
L2.insert("daydreaming");
// print the new list to verify everything got in there correctly
while (!L2.isEmpty())
System.out.print(L2.removeHead() + " ");
System.out.println();
// print the old list just to verify that there weren't any static
// problems that messed things up when we created L2
L1.printList();
}
}
It will work if you change to this:
for (node<Integer> helper = temp; helper != null && helper.next != null; helper = helper.next)
{
//start at helper.next so that temp doesn't delete it's self
if( temp.data == helper.next.data && helper.next.next != null )
{
helper.next = helper.next.next;
}
//can't seem to figure out how to delete the tail
if( temp.data == helper.next.data && helper.next.next == null )
{
helper.next = null;
}
}
That is, in the loop condition instead of:
helper.next != null
You need one more condition:
helper != null && helper.next != null
This is because after you set helper.next = null;,
the loop moves forward and executes helper = helper.next,
and then in the next iteration the loop condition helper.next != null
throws a NullPointerException because helper is null.

Remove method binary search tree

I am trying to implement a remove method for the BST structure that I have been working on. Here is the code with find, insert, and remove methods:
public class BST {
BSTNode root = new BSTNode("root");
public void insert(BSTNode root, String title){
if(root.title!=null){
if(title==root.title){
//return already in the catalog
}
else if(title.compareTo(root.title)<0){
if(root.leftChild==null){
root.leftChild = new BSTNode(title);
}
else{
insert(root.leftChild,title);
}
}
else if(title.compareTo(root.title)>0){
if(root.rightChild==null){
root.rightChild = new BSTNode(title);
}
else{
insert(root.rightChild,title);
}
}
}
}
public void find(BSTNode root, String title){
if(root!= null){
if(title==root.title){
//return(true);
}
else if(title.compareTo(root.title)<0){
find(root.leftChild, title);
}
else{
find(root.rightChild, title);
}
}
else{
//return false;
}
}
public void remove(BSTNode root, String title){
if(root==null){
return false;
}
if(title==root.title){
if(root.leftChild==null){
root = root.rightChild;
}
else if(root.rightChild==null){
root = root.leftChild;
}
else{
//code if 2 chlidren remove
}
}
else if(title.compareTo(root.title)<0){
remove(root.leftChild, title);
}
else{
remove(root.rightChild, title);
}
}
}
I was told that I could use the insert method to help me with the remove method, but I am just not seeing how I can grab the smallest/largest element, and then replace the one I am deleting with that value, then recursively delete the node that I took the replacement value, while still maintaining O(logn) complexity. Anyone have any ideas or blatant holes I missed, or anything else helpful as I bang my head about this issue?
EDIT:
I used the answers ideas to come up with this, which I believe will work but I'm getting an error that my methods (not just the remove) must return Strings, here is what the code looks like, I thought that's the return statements??
public String remove(BSTNode root, String title){
if(root==null){
return("empty root");
}
if(title==root.title){
if(root.leftChild==null){
if(root.rightChild==null){
root.title = null;
return(title+ "was removed");
}
else{
root = root.rightChild;
return(title+ "was removed");
}
}
else if(root.rightChild==null){
root = root.leftChild;
return(title+ "was removed");
}
else{
String minTitle = minTitle(root);
root.title = minTitle;
remove(root.leftChild,minTitle);
return(title+ "was removed");
}
}
else if(title.compareTo(root.title)<0){
remove(root.leftChild, title);
}
else{
remove(root.rightChild, title);
}
}
public void remove (String key, BSTNode pos)
{
if (pos == null) return;
if (key.compareTo(pos.key)<0)
remove (key, pos.leftChild);
else if (key.compareTo(pos.key)>0)
remove (key, pos.rightChild);
else {
if (pos.leftChild != null && pos.rightChild != null)
{
/* pos has two children */
BSTNode maxFromLeft = findMax (pos.leftChild); //need to make a findMax helper
//"Replacing " pos.key " with " maxFromLeft.key
pos.key = maxFromLeft.key;
remove (maxFromLeft.key, pos.leftChild);
}
else if(pos.leftChild != null) {
/* node pointed by pos has at most one child */
BSTNode trash = pos;
//"Promoting " pos.leftChild.key " to replace " pos.key
pos = pos.leftChild;
trash = null;
}
else if(pos.rightChild != null) {
/* node pointed by pos has at most one child */
BSTNode trash = pos;
/* "Promoting " pos.rightChild.key" to replace " pos.key */
pos = pos.rightChild;
trash = null;
}
else {
pos = null;
}
}
}
This is the remove for an unbalanced tree. I had the code in C++ so I have quickly translated. There may be some minor mistakes though. Does the tree you are coding have to be balanced? I also have the balanced remove if need be. I wasn't quite sure based on the wording of your question. Also make sure you add a private helper function for findMax()
void deleteTreeNode(int data){
root = deleteTreeNode(root ,data);
}
private TreeNode deleteTreeNode(TreeNode root, int data) {
TreeNode cur = root;
if(cur == null){
return cur;
}
if(cur.data > data){
cur.left = deleteTreeNode(cur.left, data);
}else if(cur.data < data){
cur.right = deleteTreeNode(cur.right, data);
}else{
if(cur.left == null && cur.right == null){
cur = null;
}else if(cur.right == null){
cur = cur.left;
}else if(cur.left == null){
cur = cur.right;
}else{
TreeNode temp = findMinFromRight(cur.right);
cur.data = temp.data;
cur.right = deleteTreeNode(cur.right, temp.data);
}
}
return cur;
}
private TreeNode findMinFromRight(TreeNode node) {
while(node.left != null){
node = node.left;
}
return node;
}
To compare objects in java use .equals() method instead of "==" operator
if(title==root.title)
^______see here
you need to use like this
if(title.equals(root.title))
or if you are interesed to ignore the case follow below code
if(title.equalsIgnoreCase(root.title))
private void deleteNode(Node temp, int n) {
if (temp == null)
return;
if (temp.number == n) {
if (temp.left == null || temp.right == null) {
Node current = temp.left == null ? temp.right : temp.left;
if (getParent(temp.number, root).left == temp)
getParent(temp.number, root).left = current;
else
getParent(temp.number, root).right = current;
} else {
Node successor = findMax(temp.left);
int data = successor.number;
deleteNode(temp.left, data);
temp.number = data;
}
} else if (temp.number > n) {
deleteNode(temp.left, n);
} else {
deleteNode(temp.right, n);
}
}
I know this is a very old question but anyways... The accepted answer's implementation is taken from c++, so the idea of pointers still exists which should be changed as there are no pointers in Java. So every time when you change the node to null or something else, that instance of the node is changed but not the original one This implementation is taken from one of the coursera course on algorithms.
public TreeNode deleteBSTNode(int value,TreeNode node)
{
if(node==null)
{
System.out.println("the value " + value + " is not found");
return null;
}
//delete
if(node.data>value) node.left = deleteBSTNode(value,node.left);
else if(node.data<value) node.right = deleteBSTNode(value,node.right);
else{
if(node.isLeaf())
return null;
if(node.right==null)
return node.left;
if(node.left==null)
return node.right;
TreeNode successor = findMax(node.left);
int data = successor.data;
deleteBSTNode(data, node.left);
node.data = data;
}
return node;
}
All the links between the nodes are pertained using the return value from the recursion.
For the Depth First Post-Order traversal and removal, use:
/*
*
* Remove uses
* depth-first Post-order traversal.
*
* The Depth First Post-order traversal follows:
* Left_Child -> Right-Child -> Node convention
*
* Partial Logic was implemented from this source:
* https://stackoverflow.com/questions/19870680/remove-method-binary-search-tree
* by: sanjay
*/
#SuppressWarnings("unchecked")
public BinarySearchTreeVertex<E> remove(BinarySearchTreeVertex<E> rootParameter, E eParameter) {
BinarySearchTreeVertex<E> deleteNode = rootParameter;
if ( deleteNode == null ) {
return deleteNode; }
if ( deleteNode.compareTo(eParameter) == 1 ) {
deleteNode.left_child = remove(deleteNode.left_child, eParameter); }
else if ( deleteNode.compareTo(eParameter) == -1 ) {
deleteNode.right_child = remove(deleteNode.right_child, eParameter); }
else {
if ( deleteNode.left_child == null && deleteNode.right_child == null ) {
deleteNode = null;
}
else if ( deleteNode.right_child == null ) {
deleteNode = deleteNode.left_child; }
else if ( deleteNode.left_child == null ) {
deleteNode = deleteNode.right_child; }
else {
BinarySearchTreeVertex<E> interNode = findMaxLeftBranch( deleteNode.left_child );
deleteNode.e = interNode.e;
deleteNode.left_child = remove(deleteNode.left_child, interNode.e);
}
} return deleteNode; } // End of remove(E e)
/*
* Checking right branch for the swap value
*/
#SuppressWarnings("rawtypes")
public BinarySearchTreeVertex findMaxLeftBranch( BinarySearchTreeVertex vertexParameter ) {
while (vertexParameter.right_child != null ) {
vertexParameter = vertexParameter.right_child; }
return vertexParameter; } // End of findMinRightBranch

java Delete a Binary Tree node containing two children

This is the last case where the node to be deleted has two children. I cant figure out what I am doing wrong . Please help.
//BTNode has two children
else if (u.getLeft() != null && u.getRight() != null){
//if node to delete is root
BTNode<MyEntry<K,V>> pred = u.getRight();
while (pred.getLeft().element() != null){
pred = pred.getLeft();
}
BTNode<MyEntry<K,V>> predParent = pred.getParent();
if (!hasRightChild(pred)){
predParent.setLeft(new BTNode<MyEntry<K,V>>(null,predParent,null,null));}
if (hasRightChild(pred)){
BTNode<MyEntry<K,V>> predChild = pred.getRight();
predParent.setLeft(predChild);
predChild.setParent(predParent);
}
return returnValue;
ok so modify it like this ??
u.setElement(succ.element());
BTNode<MyEntry<K,V>> succParent = succ.getParent();
if (!hasLeftChild(succ)){
succParent.setRight(new BTNode<MyEntry<K,V>>(null,succParent,null,null));}
if (hasLeftChild(succ)){
BTNode<MyEntry<K,V>> predChild = succ.getLeft();
succParent.setRight(predChild);
predChild.setParent(succParent);
}
return returnValue;
From wikipedia:
Deleting a node with two children: Call the node to be deleted N. Do
not delete N. Instead, choose either its in-order successor node or
its in-order predecessor node, R. Replace the value of N with the
value of R, then delete R.
So, take for example the left children, and then find the rightmost leaf in that subtree, then replace the information of the node to delete with that of the leaf, and then delete that leaf easily.
You might want to create a function that returns the rightmost leaf from a subtree.
I have given the code for deletion of a node in a BST which would work for any condition and that too using a for loop.
public void delete(int key) {
Node<E> temp = find(key);
System.out.println(temp.key);
for (;;) {
// case 1 : external node
if (temp.isExternal()) {
if (temp.getParent().getrChild() == temp) {
temp.parent.rightchild = null;
temp = null;
} else {
temp = null;
}
break;
}
// case2 : one child is null
else if ((temp.getlChild() == null) || (temp.getrChild() == null)) {
if ((temp.parent.leftchild != null) && temp.getParent().getlChild().key == temp.key) {
if (temp.getlChild() == null) {
temp.getParent().setLeft(temp.getrChild());
temp.getrChild().setParent(temp.getParent());
break;
}
else
temp.getParent().setLeft(temp.getlChild());
temp.getlChild().setParent(temp.getParent());
}
else {
if (temp.rightchild != null) {
System.out.println("in");
temp.getParent().setRight(temp.getrChild());
temp.getrChild().setParent(temp.getParent());
break;
}
else
temp.getParent().setRight(temp.getlChild());
temp.getlChild().setParent(temp.getParent());
}
break;
}
// case 3 : has both the children
else {
int t = temp.key;
temp.key = temp.getlChild().key;
temp.getlChild().key = t;
temp = temp.getlChild();
continue;
}
}
}

Categories