Last active
November 14, 2019 07:11
-
-
Save james4388/12ad3f50891a522e48651bc8d9fd3c9b to your computer and use it in GitHub Desktop.
Print linked list reversed in various ways
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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