Reversing a Linked List: the sane way, the recursive way and the push way
Reversing a SLL takes O(N). You can reverse a doubly linked list in O(1) if you swap head and tail and you’re ok with going backwards with next and vice versa.
The sane and obvious way is to use three pointers (back, middle and front); you make the middle point to back, and shift everything one step right until front is None.
def bmfReverse(self):
back = None
middle = self.head
front = middle.next
while True:
middle.next = back
if front is None: break
# advance the three pointers
back = middle
middle = front
front = front.next
self.head = middle
It is easy to turn this into a recursive function.
def recBmf(self, back=None, middle=None, front=None):
# setup
if middle is None: middle = self.head
if front is None: front = middle.next
middle.next = back
# base case
if front is None:
self.head = middle
return
return self.recBmf(middle, front, front.next)
Finally, that’s the push-reverse strategy. It’s fucked up weird to read, but the idea is actually pretty simple: you keep pushing the front node (current) on the new result list, and as a last step you update the head pointer. Source: http://cslibrary.stanford.edu/105/LinkedListProblems.pdf
def pushReverse(self):
result = None
current = self.head
while current is not None:
# save the next node
next = current.next
# move the node onto result
current.next = result
result = current
# update current
current = next
self.head = result
Bonus: reversing a doubly linked list
Oh Python, it’s not even fun this way!
def reverse(self):
n = self.head
while n is not None:
n.next, n.prev = n.prev, n.next
n = n.prev
self.head, self.tail = self.tail, self.head