TypeScript logo but with a P
Patrick Spafford Software Engineer

How to Efficiently Reverse a Linked List in Go


June 6, 2022

2 min read

views

Go programming language gopher mascot with pacifier

Problem Statement

You’re given the head of a linked list. The goal is to write a function that takes that first node and (whether iteratively or recursively) reverse the linked list. For example, if you had the linked list 2 -> 5 -> 0 -> 3 -> 8, you should be able to run some program to transform that into 8 -> 3 -> 0 -> 5 -> 2. In this post, we are going to use the recursive approach.

Definition

Let’s first define the type for a node in the linked list…

 type ListNode struct {
      Val int
      Next *ListNode
 }

Swap Function

Let’s also define a helper function for swapping nodes.

func swapNodes(node1, node2 *ListNode) *ListNode {
    node1.Next = nil // This line prevents circularity
    temp := node1
    node1 = node2
    node1.Next = temp
    return node1
}

Recursive Function with Defer

Then we need the actual recursive function. So what’s happening here? As it traverses the linked list, it pushes swap actions onto the stack using the defer statement. In other words, it traverses to the end of the linked list before making swaps in LIFO order. Our base case here is simply to return the node, which points to the head of the linked list.

func reverseListFunc(node *ListNode) *ListNode {
    if (node.Next != nil) {
        defer swapNodes(node, node.Next)
        return reverseListFunc(node.Next)
    }
    return node
}

Wrapper

Ok, so all that’s left is a trivial wrapper around this recursive function! The wrapper is there to make sure that we don’t try to reverse an empty list. And there we go, a concise and O(N) reversal of the linked list (with some sprinkles on top).

func reverseList(head *ListNode) *ListNode {
    if (head == nil) {
        return nil
    }
    return reverseListFunc(head)
}