Example #1
0
# determine if a linked list is circular ("last" node points to a node earlier in the list)
# causes infinate loops in a lot of LL logic

# use two pointers

from llist import LinkedList


def is_circular(llist):
    slow, fast = llist.head, llist.head

    while fast.next and fast.next.next:
        slow = slow.next
        fast = fast.next.next
        if slow is fast:
            return True

    return False


l = LinkedList()
for i in range(950):
    l.insert_first(f'node {i}')
assert is_circular(l) == False
end = l.get_last()
node = l.get(300)
end.next = node
assert is_circular(l)
print('All tests passed!')
# return middle node of linked list
# if size is even, return node at end of first half of list
# solve by only iterating over the list once

# use two pointers - slow & fast
# increment slow by 1, fast by 2
# when fast reaches end of list, slow should reference the middle element

from llist import LinkedList


def midpoint(llist):
    mid, end = llist.head, llist.head

    while end.next and end.next.next:
        mid = mid.next
        end = end.next.next

    return mid


l = LinkedList()
for i in range(9):
    l.insert_first(f'node {i}')
# middle is 'node 4'
assert midpoint(l).data == 'node 4'
l.insert_first('another node')
# size is now odd
assert midpoint(l).data == 'node 5'
print('All tests passed!')