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