### Deleting a specific value from an ordered list

• Delete a specific value from a list

• Deleting a specific value from a list:

 ``` delete(x): deletes the node in the last that contains the value x ```

• Given an ordered list:

• If we delete the node with the value 7 from the list, the resulting list will be:

• If we delete the node with the value 9 from the original list, the resulting list will be:

• If we delete the node with the value 4 from the original list, the resulting list will be:

• The general case to delete a specific Node in a list (= node deleted is not the first node)

• Before the deletion (e.g., delete(9) ) takes place:

• We have to find the node that contains the specified value:

• After the deletion has taken place:

• We must have a list where the deleted Node object is unchained from the list --- like this:

Note:

• The links must be unchained (disconnected) in the one-before-the-deletion node in the linked list !!

 You do not know which node is the one-before-the-deletion node in the linked list !!!

• Therefore, we must first find the one-before-the-deletion node in the list in order to make the necessary links !!!

• Finding the "one-before-the-deletion" node

• Fact:

 You can only more forward down the list You cannot go backward in a (simple) linked list

• Recall: the classic node traversal algorithm is

 ``` ptr = head; while ( ptr != null ) // Stop when there is no node { ptr = ptr.next; // Go to the next node in the list } ```

• We modifies the node traversal algorithm to stop when we have found the deletion node in a list as follows:

 ``` ptr = head; while ( ptr != null ) // Go through ALL nodes { if ( ptr.value == valueToDelete ) break; // STOP ! We found the node with the correct value ! ptr = ptr.next; // Go to the next node in the list } ```

Result:

Problem:

 It is impossible to access the one-before-the-deletion node from the deletion node !!! (Because we cannot go backward in the linked list !)

• We can use this programming trick ( click here ) to find the one-before-the-deletion node:

• Use 2 reference variables ptr1 and ptr2 that points to consecutive Nodes:

How to use these pointers:

 ptr1 will always point to the Node before the node pointed to by ptr2 We use ptr2 to find the deletion node. When ptr2 points to the deletion node, the variable ptr1 will point to the "one-before-the-deletion" node

• Algorithm to find the one-before-the-deletion node:

 ``` ptr1 = head; // ptr1 start at the first node ptr2 = head.next; // ptr2 start at the second node while ( ptr2 ≠ null ) // Go through the whole list { if ( ptr2.value == valueToDelete ) { break; // STOP ! We found the node } ptr1 = ptr2; // Use the next pair of nodes ptr2 = ptr1.next; } // When the program execution reaches this point, we have: // // ptr2 points to the node containing the deletion value // ptr1 points to the "one-before-the-deletion" node ```

• Statements to delete the deletion node from an ordered list: the general case

• Once that we have found the one-before-the-last node, deleting the last node is done as follows (as discussed above):

• Before the deletion:

• After the deletion:

Statement to achieve this result:

 ``` if ( x was found in the list ) { ptr1.next = ptr2.next; // This will delete the node with x } else { // do nothing ! } ```

• Algorithm to delete a specific node for the general case:

 ``` // Find the node with the specific value in the list /* ------------------------------------------------ Initial state: head ---> Node1 ---> Node2 ---> Node3 --->... ^ ^ | | ptr1 ptr2 ------------------------------------------------- */ Node ptr, ptr1; // ptr1 always points to the Node // before the one pointed to by ptr ptr1 = head; // ptr1 points to first node ptr = head.next; // ptr points to node following ptr1 while ( ptr2 != null ) { if ( ptr2.value == x ) { break; // STOP ! We found the node } ptr1 = ptr; // Move to next pair of node ptr = ptr.next; } // ****************************************************** // ptr2 == null is x is NOT found in the list // // Otherwise: // ptr2 points to the node with the delete value // ptr1 points to the Node BEFORE the deletion node // ****************************************************** if ( ptr2 != null ) { ptr1.next = ptr2.next; // Unlink the node ptr2 } else { // Do nothing because x was not found in the list.... } ```

• Deleting a specific Node in an ordered list: special case (when we need to update head)

• The only time that we must update the head variable when:

• The deletion node is the first node of the list

Example:

• The following test is used to detect the special case:

 ``` if ( head.value == x ) // x i sthe value that we want to delete { ... (statements to delete the first node) } ```

• Statement used to delete the first node in a list (which you have already seen):

• Before the deletion:

• After the deletion:

• Statement to achieve this:

 ``` head = head.next; ```

• The remove() method to delete a node with a specific value

• The method that deletes a node that contains a specific value x:

 ``` public class List { Node head; // Head is used to access the nodes // in the linked list /* ================================================ Constructor: initialize head to represent an empty list ================================================= */ public List() { head = null; // null means: no valid nodes } /* ============================================= The remove(x) method Note: I made the method return the value stored in the Node object ============================================= */ public double remove( double x ) throws Exception { /* ============================================== Can't delete from an empty list: error ============================================== */ if ( head == null ) throw new Exception("Remove from empty list"); /* ================================================= Here we delete the node with the value x ================================================= */ double r; // Variable used to save the value to return if ( head.value == x ) // First node has x { /* ================================================== Special case: delete the first node (updates head) =================================================== */ r = x; // Save value to return it... head = head.next; // Delete first node return r; } else { // Find the node with value x /* ------------------------------------------------ Initial state: head ---> Node1 ---> Node2 ---> Node3 --->... ^ ^ | | ptr1 ptr2 ------------------------------------------------- */ Node ptr1, ptr2; // ptr1 always points to the Node // before the one pointed to by ptr2 ptr1 = head; // ptr1 points to first node ptr2 = head.next; // ptr2 points to node following ptr1 while ( ptr2 != null ) { if ( ptr2.value == x ) { break; // Stop ! Found node with value x } ptr1 = ptr2; // Move to next pair of node ptr2 = ptr.next; } /* =================================== Delete node IF x was indeed found =================================== */ if ( ptr2 != null ) { r = x; // Save value to return it... ptr1.next = ptr2.next; return r; } // Here, we could add an else statement to // throw exception if it was not in the list... // I did not do it.... Instead, I return -1... return -1; } } } ```

• How to use the method:

 ``` public static void main( String[] args ) throws Exception { List myList = new List(); double x; myList.put(5.0); System.out.println("put(5.0): " + "myList = " + myList); myList.put(1.0); System.out.println("put(1.0): " + "myList = " + myList); myList.put(2.0); System.out.println("put(2.0): " + "myList = " + myList); myList.put(4.0); System.out.println("put(4.0): " + "myList = " + myList); myList.put(3.0); System.out.println("put(3.0): " + "myList = " + myList); myList.remove(99.0); // Will not delete any node System.out.println("remove(99.0): " + "myList = " + myList); myList.remove(3.0); System.out.println("remove(3.0): " + "myList = " + myList); myList.remove(1.0); System.out.println("remove(1.0): " + "myList = " + myList); myList.remove(5.0); System.out.println("remove(5.0): " + "myList = " + myList); myList.remove(2.0); System.out.println("remove(2.0): " + "myList = " + myList); myList.remove(4.0); System.out.println("remove(4.0): " + "myList = " + myList); } ```

Output:

 ``` put(5.0): myList = [5.0] put(1.0): myList = [1.0 , 5.0] put(2.0): myList = [1.0 , 2.0 , 5.0] put(4.0): myList = [1.0 , 2.0 , 4.0 , 5.0] put(3.0): myList = [1.0 , 2.0 , 3.0 , 4.0 , 5.0] remove(99.0): myList = [1.0 , 2.0 , 3.0 , 4.0 , 5.0] remove(3.0): myList = [1.0 , 2.0 , 4.0 , 5.0] remove(1.0): myList = [2.0 , 4.0 , 5.0] remove(5.0): myList = [2.0 , 4.0] remove(2.0): myList = [4.0] remove(4.0): myList = [] ```

• Example Program: (Demo above code)

How to run the program:

 Right click on link(s) and save in a scratch directory To compile:   javac testProg2.java To run:          java testProg2