Reverse a Singly Linked List
Let’s write a method for the SinglyLinkedList class that allows us to reverse a SinglyLinkedList
. This method should be mutating. Challenge: Try to implement this method recursively.
This method should run in Θ(n) time.
public void reverse() {
}
Hint: You might want to make a helper function or a method in the SinglyLinkedListNode
class.
Here’s the solution I came up with:
/*
* This is the reverse method of the SinglyLinkedList class.
*/
public void reverse() {
if (head == null) {
return;
} else {
head = head.reverse();
}
}
/*
* This is the reverse method of the SinglyLinkedListNode class.
* It returns a pointer to the front of the reversed list so that we
* can assign it to the head of the overall list.
*/
public SinglyLinkedListNode reverse() {
if (next == null) {
return this;
} else {
SinglyLinkedListNode currentNext = next;
this.next = null;
SinglyLinkedListNode rest = currentNext.reverse();
currentNext.next = this;
return rest;
}
}
The reverse
method for the SinglyLinkedList
class does not return anything while the reverse
method of the SinglyLinkedListNode
class returns a SinglyLinkedListNode
. The reason is because we need to have a pointer to the new front of the list in order to assign that to the head
of the list.
Let’s walk through the implementation. In the SinglyLinkedList
class, we check to see if the head
is null
. If it is, we’re done and can just return. Otherwise, we call the reverse
method of the head
and assign the return value to our head
variable which is a pointer to the front of the list.
In the SinglyLinkedListNode
class, we have a slightly more complicated problem to solve. If our next item is null, then we can simply return ourself. What that means is that if I only have one element in my list, the reverse of that list is just the single item. If that’s not the case, then we have to do some pointer manipulation. First, we need a way to store our next
node so we create a temporary variable currentNext
that will be our pointer to our next
item. Then, we’re going to set our next
to null so that we can reassign it later. Don’t worry, we still have a reference to the next
item in our variable currentNext
.
After that, we’re going to let recursion finish the rest by calling reverse
on the currentNext
. The reverse method returns a pointer to the new front of the list. This means that if our previous list was 1 -> 2 -> 3
, calling reverse
on this list would return a pointer to 3
. currentNext
still points to 2
in this case. In the next line, we’re going to be setting currentNext
’s next to be the current item. In the example above, we’re setting 2
’s next to be 1
.
Then, since we stored a pointer to the front of the list in our variable rest
, we can just return that so that we can set our head
to point to the front.
The result is a reversed list!
For testing, I simply made a linked list, called reverse, and then made sure it returned the reverse of the original list:
public static void main(String[] args) {
Object[] inOrder = {1, 2 ,3, 4, 5, 6};
SinglyLinkedList u = new SinglyLinkedList(inOrder);
System.out.println(u.toString());
u.reverse();
System.out.println(u.toString());
}
Should output:
1 2 3 4 5 6
6 5 4 3 2 1
I don't claim to be perfect so if you find an error on this page, please send me an email preferably with a link to this page so that I know what I need to fix!