10.2 Linked lists

10.2-1

We can implement INSERT in O(1) time, but cannot implement DELETE in O(1) time, it's O(n).

10.2-2

PUSH(S, x)

S.L.insert(x)
POP(S)

if S.L.head == NIL
    error "underflow"
x = S.L.head
S.L.head = S.L.head.next
return x

10.2-3

ENQUEUE(Q, x)

new = SINGLY-LINKED-NODE(x)
if Q.L.head == NIL
    Q.L.head = new
    Q.L.tail = new
else
    Q.L.tail.next = new
    Q.L.tail = new
DEQUEUE(Q)

if Q.L.head == NIL
    error "underflow"
x = Q.L.head
Q.L.head = Q.L.head.next
return x

10.2-4

LIST-SEARCH'(L, k)

x = L.nil.next
L.nil.key = k
while x.key != k
    x = x.next
if x != L.nil
    return x
else
    return NIL

10.2-5

SEARCH(D, k)

x = D.L.search(k)

if x != D.L.nil
    return x
else
    return NIL
INSERT(D, k, v)

x = SEARCH(D, k)

if x != D.L.nil:
    error "The specified key already exists"
else:
    INSERT(D.L, k, v)
DELETE(D, k)

x = SEARCH(D, k)

if x == D.L.nil:
    error "The specified key does not exist"
else:
    DELETE(D.L, k)

The running time of INSERT, DELETE and SEARCH are all O(n).

10.2-6

We can use two singly linked lists to represent s1 and s2. In order to union s1 and s2, we simply let the tail of s1 points to the head of s2, and let the tail of s2 be the tail of s1.

SET-UNION(s1, s2)

s1.tail.next = s2.head
s1.tail = s2.tail

return s1

10.2-7

REVERSE-SINGLY-LINKED-LIST(L)

prev = L.head
current = prev.next if prev != NIL else NIL

while current != NIL
    next = current.next
    current.next = prev
    prev = current
    current = next

L.head.next = NIL
temp = L.head
L.head = L.tail
L.tail = temp

10.2-8

We can use the memory addresses of the pointers as the k-bit integers, so x.np = memory-address(x.next) XOR memory-address(x.pre).

SEARCH(L, k)

node = L.head
prev-pointer = 0

while node != NIL and node.key != k:
    if node == L.tail:
        return NIL

    new-prev-pointer = memory-address(node)
    node = value-at-memory-address(node.np XOR prev-pointer)
    prev-pointer = new-prev-pointer

return node
INSERT(L, k)

new = ONE-POINTER-DOUBLY-LINKED-NODE(key)

if L.head is NIL:
    L.head = new
    L.head.np = 0 XOR 0
    L.tail = new
    L.tail.np = 0 XOR 0
else:
    new.np = memory-address(L.head) XOR 0
    L.head.np = (L.head.np XOR 0) XOR memory-address(new)
    L.head = new
DELETE(L, k)

node = L.head
prev-pointer = 0
prev-node = NIL

while node != NIL and node.key != key:
    if node == L.tail:
        error "The specified key does not exist"

    new-prev-pointer = memory-address(node)
    prev-node = node
    node = value-at-memory-address(node.np XOR prev-pointer)
    prev-pointer = new-prev-pointer

if node == NIL:
    error "The specified key does not exist"

if node == L.head:
    if L.head == L.tail:
        L.head = NIL
        L.tail = NIL
    else:
        next = value-at-memory-address(node.np XOR 0)
        next.np = (next.np XOR memory-address(node)) XOR 0
        L.head = next
else if node == L.tail:
    prev-node.np = (prev-node.np XOR memory-address(node)) XOR 0
    L.tail = prev-node
else:
    next = value-at-memory-address(node.np XOR prev_pointer)
    next.np = (next.np XOR memory-address(node)) XOR prev-pointer
    prev-node.np = (prev-node.np XOR memory-address(node)) XOR memory-address(next)
REVERSE(L)

temp = L.head
L.head = L.tail
L.tail = temp