Skip to content

Instantly share code, notes, and snippets.

@james4388
Last active November 14, 2019 07:11
Show Gist options
  • Save james4388/12ad3f50891a522e48651bc8d9fd3c9b to your computer and use it in GitHub Desktop.
Save james4388/12ad3f50891a522e48651bc8d9fd3c9b to your computer and use it in GitHub Desktop.
Print linked list reversed in various ways
class Node:
def __init__(self, value):
self.value = value
self.next = None
def length(head):
"""Get linked list length"""
count = 0
node = head
while node:
count += 1
node = node.next
return count
def print_reverse_recursive(head):
"""Print a linked list using resursion
Time: O(N)
Space: O(N) function call stack store
Usage: print_reverse_recursive(head)
"""
if not head:
return
print_reverse_recursive(head.next)
print(head.value)
def print_reverse_half(start, end):
"""Devide the list in half eachtime using turtle and hare pointer
Time: O(NlogN)
Space: O(log(N)) function call stack store
Usage: print_reverse_half(head, None)
"""
if start == end:
return
# Find the midle node
slow = fast = start
while fast.next != end and fast.next.next != end:
fast = fast.next.next
slow = slow.next
print_reverse_half(slow.next, end)
print(slow.value)
print_reverse_half(start, slow)
def print_reverse_stack(head):
"""Using temporaty storage
Time: O(N)
Space: O(N)
"""
stack = []
node = head
while node:
stack.append(node.value)
node = node.next
while stack:
print(stack.pop())
def print_reverse_string(head):
"""Using string, cheated
Time: O(N) or O(N^2) if you count string manipulate time (copy string over and over)
Space: O(N) although it look like O(1) but string is actually an array of char
"""
buffer = ''
node = head
while node:
buffer = str(node.value) + ' ' + buffer
node = node.next
print(buffer)
def print_reverse_chunks(head, chunk_size=None):
"""Split the list into smaller chunks (store chunk's head in stack)
print each chunk in reverse using smaller stack space.
only saving space when number of nodes is larger than chunk_size
Add more level: https://en.wikipedia.org/wiki/Skip_list
"""
if chunk_size is None:
n = length(head) # Time O(N)
chunk_size = (n // 10) or 1
# Collect node, skip every chunk_size
chunk_stack = [] # Space O(N / chunk_size)
i = 0
node = head
while node:
if i % chunk_size == 0:
chunk_stack.append(node)
i += 1
node = node.next
while chunk_stack:
chunk_head = chunk_stack.pop()
stack = []
i = 0
while chunk_head and i < chunk_size:
stack.append(chunk_head.value)
chunk_head = chunk_head.next
i += 1
while stack:
print(stack.pop())
def reverse_linked_list(head):
""" Reverse a linked list
Time: O(N)
Space: O(1)
"""
if not head:
return
node = head
prev = None
while node:
node.next, prev, node = prev, node, node.next
return prev
def print_ll(head):
"""Print a linked list"""
node = head
while node:
print(node.value)
node = node.next
def print_reverse_reversed(head):
"""Reverse a linked list then print normal then reverse again
Time: O(3N) = O(N)
Space: O(1)
*Not thread safe
"""
head = reverse_linked_list(head)
print_ll(head)
head = reverse_linked_list(head)
def create_linked_list(n):
"""Create linked list from 0 to n-1 for testing"""
head = Node(0)
node = head
for i in range(1, n):
node.next = Node(i)
node = node.next
return head
if __name__ == '__main__':
head = create_linked_list(20)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment