Here's a basic implementation of a custom doubly linked list
in Java. This implementation includes common operations such as adding
elements, removing elements, and displaying the list.
Custom Doubly Linked List Implementation
java
public class
CustomDoublyLinkedList<E> { private Node<E> head; private Node<E> tail; private int size; // Node class to represent each element
in the list private static class Node<E> { E data; Node<E> next; Node<E> prev; Node(E data, Node<E> next,
Node<E> prev) { this.data = data; this.next = next; this.prev = prev; } } // Default constructor public CustomDoublyLinkedList() { head = null; tail = null; size = 0; } // Add element to the end of the list public void add(E element) { if (tail == null) { head = tail = new
Node<>(element, null, null); } else { Node<E> newNode = new
Node<>(element, null, tail); tail.next = newNode; tail = newNode; } size++; } // Add element at a specific index public void add(int index, E element) { checkIndexForAdd(index); if (index == size) { add(element); } else { Node<E> current =
getNode(index); Node<E> newNode = new
Node<>(element, current, current.prev); if (current.prev != null) { current.prev.next = newNode; } else { head = newNode; } current.prev = newNode; size++; } } // Get element at a specific index public E get(int index) { checkIndex(index); return getNode(index).data; } // Set element at a specific index public void set(int index, E element) { checkIndex(index); getNode(index).data = element; } // Remove element at a specific index public void remove(int index) { checkIndex(index); Node<E> nodeToRemove =
getNode(index); if (nodeToRemove.prev != null) { nodeToRemove.prev.next =
nodeToRemove.next; } else { head = nodeToRemove.next; } if (nodeToRemove.next != null) { nodeToRemove.next.prev =
nodeToRemove.prev; } else { tail = nodeToRemove.prev; } size--; } // Get the size of the list public int size() { return size; } // Check if the list is empty public boolean isEmpty() { return size == 0; } // Display the list from head to tail public void printList() { Node<E> current = head; while (current != null) { System.out.print(current.data +
" <-> "); current = current.next; } System.out.println("null"); } // Get the node at a specific index private Node<E> getNode(int index)
{ Node<E> current = head; for (int i = 0; i < index; i++) { current = current.next; } return current; } // Check if index is within bounds for
add operations private void checkIndexForAdd(int index)
{ if (index < 0 || index > size)
{ throw new
IndexOutOfBoundsException("Index: " + index + ", Size: "
+ size); } } // Check if index is within bounds for
get and remove operations private void checkIndex(int index) { if (index < 0 || index >= size)
{ throw new
IndexOutOfBoundsException("Index: " + index + ", Size: "
+ size); } } // Main method for testing public static void main(String[] args) { CustomDoublyLinkedList<String>
list = new CustomDoublyLinkedList<>(); list.add("A"); list.add("B"); list.add("C"); list.add(1, "D"); // Add
"D" at index 1 System.out.println("List after
additions:"); list.printList(); // Output: A
<-> D <-> B <-> C <-> null System.out.println("Element at
index 2: " + list.get(2)); // Output: Element at index 2: B list.set(2, "E"); System.out.println("List after
setting index 2 to 'E':"); list.printList(); // Output: A
<-> D <-> E <-> C <-> null list.remove(1); System.out.println("List after
removing element at index 1:"); list.printList(); // Output: A
<-> E <-> C <-> null System.out.println("Size of the
list: " + list.size()); // Output: Size of the list: 3 } } |
Key Components
- Node
Class: Represents each element in the list with data, next, and prev
references.
- Add
Methods:
- add(E
element): Adds an element to the end of the list.
- add(int
index, E element): Adds an element at a specific index.
- Get
Method: Retrieves the element at a specified index.
- Set
Method: Updates the element at a specified index.
- Remove
Method: Removes the element at a specified index.
- Size
and Empty Check: Provides methods to get the size of the list and
check if it is empty.
- Print
List: Displays the contents of the list with <-> to denote links
between nodes.
- Index
Checking: Methods to check for index validity, ensuring operations do
not go out of bounds.
This implementation provides a foundational understanding of
doubly linked lists, including how to manage nodes in both forward and backward
directions. You can further enhance this implementation by adding more
functionalities or optimizations as needed.
2 Comments
The content of the blog was useful.Thanks for sharing.
- Apoorva.D