Footprints in both directions

Doubly Linked Lists

The analogy

Now each clue also says where you came from, so you can walk the hunt backwards. It costs a bit more paper on every clue, but you are never stuck facing one way.

Visualizer

Footprints in both directions

step 1 / 12
headโ†’4โ†’8โ†’15โ†’16โ†’null

Same list, but every node now also remembers where it came from. Two pointers per node instead of one.head โ‡„ 4 โ‡„ 8 โ‡„ 15 โ‡„ 16 โ‡„ null

๐Ÿ“– In depth โ€” the full reference

Singly vs doubly linked

abilitysinglydoublyprice of doubly
walk forwardO(1)/hopO(1)/hopโ€”
walk backwardimpossible without re-walkingO(1)/hopone extra pointer per node
delete a node you HOLDO(n) โ€” must find its previousO(1) โ€” node.prev is right thereevery insert must wire 4 pointers, not 2
insert before a held nodeO(n)O(1)same
memory per nodevalue + 1 pointervalue + 2 pointers+8 bytes/node

collections.deque โ€” the doubly linked workhorse

operationcostnote
append(x) / appendleft(x)O(1)both ends are first-class
pop() / popleft()O(1)this is why BFS uses deque, never list.pop(0)
d[i] middle accessO(n)it is a list of blocks, not an array
maxlen=kauto-evictsa rolling window in one argument
rotate(k)O(k)carousel behaviour for free

See it yourself

from collections import deque
history = deque(maxlen=3)          # a browser's back button
for page in ['a', 'b', 'c', 'd']:
    history.append(page)
print(list(history))                # ['b', 'c', 'd'] โ€” 'a' fell off
history.pop()                        # go back: O(1)
history.appendleft('start')         # O(1) at the other end too
def remove(node):
    node.prev.next = node.next
    node.next.prev = node.prev
# O(1) โ€” no search for a predecessor

from collections import deque
d = deque([4, 8, 15])
d.appendleft(1)   # O(1) at BOTH ends
d.pop()           # O(1)
Check yourself

The extra prev pointer buys youโ€ฆ

Practice โ€” write it yourself

count_nodes(head) walks a linked list ({"value", "next"} dicts) and returns how many nodes it has. No lists allowed โ€” just the walk.

Python 3 ยท runs in your browser ยท your draft is saved locally
๐Ÿ“ My notessaved in this browser