Exploring Linked Lists in Java: Types and Operations
Published: 2023-08-28 05:39:02

> Linked lists are fundamental data structures used in computer science to store and manage collections of data. They consist of nodes, each holding a value and a reference to the next node in the sequence. Linked lists come in different types, such as singly linked lists, doubly linked lists, and circular linked lists, each with its own characteristics. In this blog post, we'll delve into the various types of linked lists and explore how to perform common operations on them using Java.

## But wait where do we acutally use this Linked lists?

- Memory Allocation: Linked lists allow efficient memory allocation for varying sizes of data. Unlike arrays, which have a fixed size, linked lists can allocate memory as needed, helping to prevent memory wastage.

- Undo Functionality: In applications where users can perform actions that need to be reversible (like in text editors or graphic design software), a linked list can be used to maintain a history of actions, enabling the "undo" feature.

- Music and Video Playlists: Linked lists can represent playlists where each node corresponds to a song or video. Users can easily move to the next or previous item in the playlist by following the links.

- Browsers' Forward and Backward Navigation: Web browsers use linked lists to implement the forward and backward navigation functionality. Each visited page is a node, and users can navigate by moving forward or backward through the linked list.

- Operating Systems: Linked lists are employed by operating systems to manage processes, threads, and other system resources. This dynamic structure facilitates efficient allocation and deallocation of resources.

- Garbage Collection: In programming languages with automatic memory management (like Java), linked lists play a role in garbage collection algorithms, helping to identify and reclaim memory that is no longer needed.

- Graph Algorithms: Some graph algorithms, like Dijkstra's algorithm for finding shortest paths, use linked lists to maintain priority queues of vertices.


## Types of Linked Lists:

**Singly Linked List:**
_In a singly linked list, each node contains data and a reference to the next node. The last node's reference points to null, indicating the end of the list. Singly linked lists are memory-efficient and support forward traversal._

**Doubly Linked List:**
_In a doubly linked list, nodes have data, a reference to the next node, and a reference to the previous node. This bidirectional linking enables efficient traversal in both directions, but it comes at the cost of increased memory usage._

**Circular Linked List:**
_Circular linked lists can be either singly or doubly linked. The last node's reference in a singly circular linked list points back to the first node, forming a loop. In a doubly circular linked list, the last node's reference points to the previous node. Circular linked lists are useful for applications that involve cyclic operations._

## Common Operations on Linked Lists:

**Insertion:**
**Insert at the Beginning:**
_Adding a new node at the beginning of a linked list involves creating a new node, setting its reference to the current head, and updating the head to point to the new node._

```
void insertAtBeginning(int data) {
    Node newNode = new Node(data);
    newNode.next = head;
    head = newNode;
}
```

**Insert at the End:**
_To add a node at the end, traverse the list until you reach the last node, then update its reference to the new node._

```
void insertAtEnd(int data) {
    Node newNode = new Node(data);
    if (head == null) {
        head = newNode;
        return;
    }
    Node current = head;
    while (current.next != null) {
        current = current.next;
    }
    current.next = newNode;
}
```

**Traversal:**
_Traversing a linked list means visiting each node to access or manipulate its data. This is often done using a loop that iterates through the nodes, following their references._

```
void traverse() {
    Node current = head;
    while (current != null) {
        System.out.print(current.data + " ");
        current = current.next;
    }
}
```

**Deletion:**
Delete from the Beginning:
_Removing the first node involves updating the head to point to the second node._

```
void deleteFromBeginning() {
    if (head == null) {
        return;
    }
    head = head.next;
}
```

**Delete from the End:**
_Deleting the last node requires finding the second-to-last node and updating its reference to null._

```
void deleteFromEnd() {
    if (head == null || head.next == null) {
        head = null;
        return;
    }
    Node current = head;
    while (current.next.next != null) {
        current = current.next;
    }
    current.next = null;
}
```

Linked lists are versatile structures with a wide range of applications in computer science. Understanding their types and operations is essential for developing efficient algorithms and data management systems. By mastering linked lists, you'll gain valuable insights into memory management and data organization.