| package
  com.kartik;   /** * * @author Kartik Mandal * Blog https://www.javatherapy.in/ * A
  singly-linked list is an algorithm that puts elements of a list in a certain
  order * This will
  display the linked list data where I mentioned generic class of Linked list
  and class itself recursive. * @date Feb 25,
  2015 */ public class LinkedListRec<E>
  { // here,
  include the LinkedNode definition private static class LinkedNode<T>
  { private T item; private LinkedNode<T> next; /** * Constructor for creating a node without a successor. * @param the value to be held by this node. */ private LinkedNode(T value)
  { item = value; next = null; } /** * Constructor for creating a node with a specified (possibly null) successor. * @param the value to be held by this node. * @param the successor node for this instance. */ private LinkedNode(T value,
  LinkedNode<T> reference) { item = value; next = reference; } } // Conclusion of the LinkedNode definition. // This marks the beginning of the linked list. If the list is empty, it is represented as null. protected LinkedNode<E> head; /** * Initializes a linked list that is empty. */ public LinkedListRec()
  { head = null; } 
 /** A private recursive method invoked by the public wrapper method. * @param the head of the list (can be null if at the end). * @return the total size of the list. */ private int size(LinkedNode<E> current)
  { if (current == null)
  { return 0; // An empty list has a size of 0, } // while a non-empty list has a size that is 1 greater than the remainder of the list. return 1
  + size (current.next); } /** Public wrapper method that calls the private recursive method. * @param none * @return the total size of the list. */ public int size()
  { return size(head); } /** A private recursive method called by the public wrapper method. * @param the head of the list (can be null if at the end). * @param the value to be appended. * @return the list with the new value included. */ private LinkedNode<E>
  addAtEnd(LinkedNode<E> node, E value) { if (node == null)
  { return new LinkedNode<E>(value); } node.next =
  addAtEnd(node.next, value); return node; } /** Public wrapper method that invokes the private recursive method. * @param the value to be appended to the end of the linked list. */ public void add(E value)
  { head =
  addAtEnd(head, value); } /** A private recursive method called by the public wrapper method. * @param the head of the list (can be null if at the end). * @param the number of nodes to bypass before inserting. * @param the value to be added. * @return the list with the new value included. */ private LinkedNode<E>
  addAtPosition(LinkedNode<E> node, int skip,
  E value) { if (skip ==
  0) { return new LinkedNode<E>(value, node); 
 } if (node == null)
  { // If the node is null but the skip count is greater than 0, it indicates an invalid index. throw new IndexOutOfBoundsException("bad
  index for add"); } node.next =
  addAtPosition(node.next, skip - 1, value); return node; } /** Public wrapper method that calls the private recursive method. * @param the position for insertion: 0 to insert at the beginning. * @param the
  value to be added * @throws IndexOutOfBoundsException if the index is less than 0 or exceeds the number of elements in the linked list. */ public void add(int index,
  E value) { head =
  addAtPosition(head, index, value); } /** A private recursive method called by the public wrapper method. * @param the head of the list (can be null if at the end). * @param the
  value to be removed. * @return tthe list with the specified value removed. */ private LinkedNode<E>
  remove(LinkedNode<E> node, E value) { if (node == null) { // A match is found, so this node will be null but skip > 0 -- it indicates an invalid index. return node; } if (node.item.equals(value))
  { return node.next; //
  Eliminate this node as it matches the criteria. } node.next =
  remove(node.next, value); return node; } /** This public wrapper method invokes the private recursive method. * @param the object intended for removal. */ public void remove(E value)
  { head =
  remove(head, value); } /** This private recursive method is called by the public wrapper method. * @param the head of the list (can be null if at the end). * @return a string that represents the list. */ private String
  toString(LinkedNode<E> node) { if (node == null)
  { return ""; } if (node.next == null)
  { return node.item.toString(); } return node.item.toString()
  + " ==> " + toString(node.next); } /** *
  Combines the elements of the linked list, using " ==> " as a separator. * @return the string representation of the list. */ public String
  toString() { return toString(head); } /** * Unit test method for fundamental functionality testing. * @param required, which is disregarded. */ public static void main
  (String [] arguments) { LinkedListRec<String> ll = new LinkedListRec<String>(); System.out.println
  (ll); ll.add("Mandal"); System.out.println
  (ll); ll.add(1, "Chandra"); System.out.println
  (ll); ll.add("Java"); System.out.println
  (ll); ll.add(0, "hello"); System.out.println
  (ll); ll.add("foo"); ll.add("baz"); ll.add(0, "hello"); System.out.println
  (ll); ll.remove
  ("foo"); // eliminate a middle element System.out.println
  (ll); ll.remove
  ("hello"); // eliminate the first element System.out.println
  (ll); ll.remove
  ("baz"); // eliminate the last element System.out.println
  (ll); ll.add("Kartik"); System.out.println
  (ll); } } | 
LinkedListRec class is a recursive implementation of a
singly linked list that supports basic operations like adding, removing
elements, and displaying the list as a string. Here's a breakdown of how it
works:
Structure:
Ø  Node
Class:
ü 
The LinkedNode<T> class represents a node
in the linked list, holding an item and a reference to the next node.
ü 
Two constructors are provided, one to create a
node without a successor and one to create a node with a specified successor.
Ø  Linked
List Class:
ü 
The LinkedListRec<E> class contains a
reference to the head of the list (head).
ü 
Various methods operate recursively on the list,
using helper methods to manipulate nodes.
Operations:
- Size:
ü 
The method size() calculates the size of the
list recursively by counting nodes until null is reached.
- Adding
     Elements:
ü 
add(E value): Adds an element at the end
of the list.
ü 
add(int index, E value): Adds an element
at a specific position. The recursive function ensures that nodes are skipped
correctly.
- Removing
     Elements:
ü 
remove(E value): Removes the first
occurrence of a given element. It finds the node with a matching value and
bypasses it by returning its successor.
- String
     Representation:
ü 
toString(): Converts the linked list into
a string where the elements are separated by " ==> ".
Example Execution:
Here’s what happens in the main method step by step:
- Creates
     an empty linked list.
- Adds
     elements like "Mandal", "Chandra", and
     "Java".
- Adds
     elements at specific positions using an index.
- Removes
     elements by value.
- Prints
     the current state of the list at various stages.
Sample Output:
When you run the main method, the output will look something
like this (depending on the internal operations):
text
| // Initial
  empty list // After
  adding "Mandal" Mandal // After
  adding "Chandra" at index 1 Mandal ==>
  Chandra // After
  adding "Java" at the end Mandal ==>
  Chandra ==> Java // Adding
  "hello" at index 0 hello ==>
  Mandal ==> Chandra ==> Java // After
  adding more elements hello ==>
  Mandal ==> Chandra ==> Java ==> foo ==> baz // Removing
  "foo" hello ==>
  Mandal ==> Chandra ==> Java ==> baz // Removing
  "hello" Mandal ==>
  Chandra ==> Java ==> baz // Removing
  "baz" Mandal ==>
  Chandra ==> Java // Adding
  "Kartik" Mandal ==>
  Chandra ==> Java ==> Kartik | 
We need to do below three Improvements & Suggestions:
- Boundary
     Handling:
- In
      methods like addAtPosition, it's good to handle cases where the index is
      out of bounds more explicitly.
- Efficiency:
- You
      might consider iterative versions of some methods for better performance,
      though recursion keeps the code elegant.
- Null
     Handling:
- Ensure
      you handle null values appropriately, especially for the remove method,
      to avoid NullPointerException.
This implementation provides a clean and functional
recursive solution for a singly linked list!
 
0 Comments