Post

Singly Linked Lists in Kotlin: The Complete Guide

Singly Linked Lists in Kotlin: The Complete Guide

Singly Linked Lists in Kotlin: The Complete Guide

While Arrays are great for indexed access, Linked Lists shine when it comes to dynamic memory allocation and efficient insertions/deletions. In a Singly Linked List, each element is a “Node” that contains data and a reference to the next node in the sequence.

In this guide, we will implement a Singly Linked List in Kotlin and cover all essential operations: Insertion, Deletion, and Reversal.


The Foundation: The Node Class

In Kotlin, we can represent a Node using a data class.

1
data class Node(val data: Int, var next: Node? = null)

1. Insertion Operations

Unlike arrays, we don’t need to “shift” elements when inserting into a Linked List. We simply update the pointers.

Insert at Head ($O(1)$)

1
2
3
4
5
fun insertAtFirst(head: Node?, key: Int): Node {
    val newNode = Node(data = key)
    newNode.next = head
    return newNode
}

Insert at End ($O(n)$)

We must traverse to the very last node where next is null, then attach our new node.

1
2
3
4
5
6
7
8
9
fun insertAtEnd(head: Node, key: Int): Node {
    val newNode = Node(data = key)
    var currNode: Node? = head
    while (currNode?.next != null) {
        currNode = currNode.next
    }
    currNode?.next = newNode
    return head
}

2. Deletion Operations

To delete a node, we find the node before the one we want to remove and change its next pointer to skip the unwanted node.

Delete at Position

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
fun deleteNodeAtPosition(head: Node?, position: Int): Node? {
    if (head == null) return head
    if (position == 1) {
        val newHead = head.next
        head.next = null
        return newHead
    }

    var currNode = head
    for (i in 1..< position - 1) {
        if (currNode == null) break
        currNode = currNode.next
    }

    if (currNode?.next == null) return head
    
    currNode.next = currNode.next?.next
    return head
}

3. The Interview Classic: Reversing a Linked List

Reversing a list in-place requires managing three pointers: prev, current, and next.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fun reverseLinkedList(head: Node?): Node? {
    if (head == null) return head

    var current: Node? = head
    var prev: Node? = null
    var next: Node? = null

    while (current != null) {
        next = current.next    // 1. Save next
        current.next = prev    // 2. Reverse link
        
        prev = current         // 3. Move prev forward
        current = next         // 4. Move current forward
    }
    return prev // New head
}

Summary Table: Time Complexity

OperationComplexityDescription
Access/SearchO(n)Must traverse from head.
Insert (Head)O(1)Immediate pointer update.
Insert (End)$O(n)Must find the tail first.
Delete (Head)O(1)Move the head pointer.

Source Code

🚀 Code: All the code for this tutorial is available in my DSA-Kotlin Repository.

This post is licensed under CC BY 4.0 by the author.