A Linked List Is Recursive

So far we have used the word recursion for methods: a method is recursive when it calls itself. Data can be recursive too. The simplest example is the linked list.

Earlier in the course we built a list without an array, as a linked list of Node objects. Each node holds a value and a next reference to the node after it, and the last node’s next is null:

private static class Node<T> {
  T value;
  Node<T> next;
}

Here is a list of three values:

         ┌───┐     ┌───┐     ┌───┐
head ──▶ │ 3 │ ──▶ │ 5 │ ──▶ │ 7 │ ──▶ null
         └───┘     └───┘     └───┘

Now look at what next points to. It points to another Node, the head of the rest of the list. And the rest of the list is itself a shorter linked list:

         ┌───┐     ┌───┐
...  ──▶ │ 5 │ ──▶ │ 7 │ ──▶ null
         └───┘     └───┘

The list 5 ──▶ 7 ──▶ null is a linked list, and so are 7 ──▶ null and null, the empty list. The whole list is just the value 3 placed in front of one of these smaller lists.

So a linked list is one of two things:

  • the empty list, written null, or
  • a node holding a value, followed by a linked list.

The definition mentions a linked list inside its own description, in the second case. That is not a mistake. A recursive method does the same thing: its body calls the method on a smaller input. The empty list is where the definition stops, so it plays the role of a base case. The second case reduces a list to a value plus a smaller list, which is what a recursive case does to a problem.

This is what we mean by a recursive data structure: a structure defined in terms of a smaller version of itself. Each node is followed by exactly one smaller list. That is the same shape as the call tree of factorial, which is a single chain because each call makes one call below it.