Delete Node
by Isai Damier, Android Engineer @ Google

/***************************************************************************
 * Author: Isai Damier
 * Title: Singly Linked List
 * Project: geekviewpoint
 * Package: datastructure
 *
 * Description: A LinkedList is a data structure that allows access
 *   to a collection of data using pointers/references. While an
 *   array can also be defined as above, LinkedLists and arrays differ
 *   in how they are stored in memory and in the operations they
 *   allow. Unlike an array that must be stored in a block of memory,
 *   the nodes of a LinkedList can be stored anywhere because each
 *   node has a reference to the node that succeeds it. Because the
 *   nodes are stored so loosely, inserting nodes into a LinkedList
 *   is easy; whereas in an array, all the succeeding elements must
 *   be shifted. Of course, insertion also means changing the size of
 *   the array, which means creating the entire array anew.
 *
 *   Perhaps the greatest beauty of LinkedList is that it allows
 *   accessing an entire sequence of nodes using only one variable:
 *   a reference to the first node in the sequence.
 *
 *   Countless operations can be performed on LinkedLists. Following
 *   are a few, ranging from the common to the very interesting.
 **************************************************************************/ 
 public class SinglyLinkedList {

  Node head = null;
  Node tail = null;

  /*****************************************************************
   * Description: Delete and retrieve the specified node.
   *
   *   One of the drawbacks of LinkedList is that
   *   it allows no random access. Therefore deleting a random
   *   node is a O(n) process because the list must first be
   *   traversed to find the node containing the element.
   *
   * Technical Details:
   *   0] If node is the head, simply delete from head and return: O(1).
   *   1] If node is the tail, simply delete from tail and return: O(1).
   *   2] Otherwise, find the node's parent.
   *   3] If the nod is found, give parent custody of node's child.
   *   4] Return the node.
   *****************************************************************/
  public boolean delete(Node n) {
    if (null == n) {
      return false;
    }
    if (n == head) {
      deleteFromHead();
      return true;
    }
    if (n == tail) {
      deleteFromTail();
      return true;
    }
    Node parent = null, curr = head;
    while (null != curr && n != curr) {
      parent = curr;
      curr = curr.next;
    }
    if (n == curr) {
      parent.next = curr.next;
      return true;
    }
    return false;
  }
}
public class SinglyLinkedListTest {

   /**
   * Test of delete method, of class SinglyLinkedList.
   */
  @Test
  public void testDelete_Node() {
    System.out.println("delete");
    int[] input = {9, 4, 5, 2, 1, 12, 6, 7, 4, 8, 3, 0, 16, 19, 11};
    SinglyLinkedList linkedList = new SinglyLinkedList();
    for (int i = 0; i < input.length; i++) {
      linkedList.addToTail(input[i]);
    }
    Node n = linkedList.find(input[0]);
    assertEquals(true, linkedList.delete(n));
    n = linkedList.find(input[5]);
    assertEquals(true, linkedList.delete(n));
    int last = input.length - 1;
    n = linkedList.find(input[last]);
    assertEquals(true, linkedList.delete(n));
    assertEquals(false, linkedList.delete(null));
    int[] expected = {4, 5, 2, 1, 6, 7, 4, 8, 3, 0, 16, 19};
    assertTrue(Arrays.equals(expected, linkedList.toArray()));
  }
}