Implementing pointers and objects
Implementing pointers and objects
10.2-6
The dynamic-set operation U NION takes two disjoint sets S1 and S2 as input, and
it returns a set S D S1 [ S2 consisting of all the elements of S1 and S2 . The
sets S1 and S2 are usually destroyed by the operation. Show how to support U NION
in O.1/ time using a suitable list data structure.
10.2-7
Give a ‚.n/-time nonrecursive procedure that reverses a singly linked list of n
elements. The procedure should use no more than constant storage beyond that
needed for the list itself.
10.2-8 ?
Explain how to implement doubly linked lists using only one pointer value x:np per
item instead of the usual two (next and pre�). Assume that all pointer values can be
interpreted as k-bit integers, and define x:np to be x:np D x:next XOR x:pre�,
the k-bit “exclusive-or” of x:next and x:pre�. (The value NIL is represented by 0.)
Be sure to describe what information you need to access the head of the list. Show
how to implement the S EARCH, I NSERT, and D ELETE operations on such a list.
Also show how to reverse such a list in O.1/ time.
How do we implement pointers and objects in languages that do not provide them?
In this section, we shall see two ways of implementing linked data structures with-
out an explicit pointer data type. We shall synthesize objects and pointers from
arrays and array indices.
1 2 3 4 5 6 7 8
L 7
next 3 2 5
key 4 1 16 9
prev 5 2 7
Figure 10.5 The linked list of Figure 10.3(a) represented by the arrays key, next, and pre�. Each
vertical slice of the arrays represents a single object. Stored pointers correspond to the array indices
shown at the top; the arrows show how to interpret them. Lightly shaded object positions contain list
elements. The variable L keeps the index of the head.
attribute of the tail and the pre� attribute of the head, we usually use an integer
(such as 0 or 1) that cannot possibly represent an actual index into the arrays. A
variable L holds the index of the head of the list.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
L 19
A 4 7 13 1 4 16 4 19 9 13
key prev
next
Figure 10.6 The linked list of Figures 10.3(a) and 10.5 represented in a single array A. Each list
element is an object that occupies a contiguous subarray of length 3 within the array. The three
attributes key, next, and pre� correspond to the offsets 0, 1, and 2, respectively, within each object.
A pointer to an object is the index of the first element of the object. Objects containing list elements
are lightly shaded, and arrows show the list ordering.
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
free 4 free 8
L 7 next 3 8 2 1 5 6 L 4 next 3 7 2 1 5 6
key 4 1 16 9 key 4 1 25 16 9
prev 5 2 7 prev 5 2 7 4
(a) (b)
1 2 3 4 5 6 7 8
free 5
L 4 next 3 7 8 1 2 6
key 4 1 25 9
prev 7 2 4
(c)
Figure 10.7 The effect of the A LLOCATE -O BJECT and F REE -O BJECT procedures. (a) The list
of Figure 10.5 (lightly shaded) and a free list (heavily shaded). Arrows show the free-list structure.
(b) The result of calling A LLOCATE -O BJECT./ (which returns index 4), setting keyŒ4� to 25, and
calling L IST-I NSERT.L; 4/. The new free-list head is object 8, which had been nextŒ4� on the free
list. (c) After executing L IST-D ELETE.L; 5/, we call F REE -O BJECT.5/. Object 5 becomes the new
free-list head, with object 8 following it on the free list.
A LLOCATE -O BJECT ./
1 if free == NIL
2 error “out of space”
3 else x D free
4 free D x:next
5 return x
The free list initially contains all n unallocated objects. Once the free list has been
exhausted, running the A LLOCATE -O BJECT procedure signals an error. We can
even service several linked lists with just a single free list. Figure 10.8 shows two
linked lists and a free list intertwined through key, next, and pre� arrays.
The two procedures run in O.1/ time, which makes them quite practical. We
can modify them to work for any homogeneous collection of objects by letting any
one of the attributes in the object act like a next attribute in the free list.
10.3 Implementing pointers and objects 245
free 10 1 2 3 4 5 6 7 8 9 10
next 5 6 8 2 1 7 4
L2 9
key k1 k2 k3 k5 k6 k7 k9
L1 3 prev 7 6 1 3 9
Figure 10.8 Two linked lists, L1 (lightly shaded) and L2 (heavily shaded), and a free list (dark-
ened) intertwined.
Exercises
10.3-1
Draw a picture of the sequence h13; 4; 8; 19; 5; 11i stored as a doubly linked list
using the multiple-array representation. Do the same for the single-array represen-
tation.
10.3-2
Write the procedures A LLOCATE -O BJECT and F REE -O BJECT for a homogeneous
collection of objects implemented by the single-array representation.
10.3-3
Why don’t we need to set or reset the pre� attributes of objects in the implementa-
tion of the A LLOCATE -O BJECT and F REE -O BJECT procedures?
10.3-4
It is often desirable to keep all elements of a doubly linked list compact in storage,
using, for example, the first m index locations in the multiple-array representation.
(This is the case in a paged, virtual-memory computing environment.) Explain
how to implement the procedures A LLOCATE -O BJECT and F REE -O BJECT so that
the representation is compact. Assume that there are no pointers to elements of the
linked list outside the list itself. (Hint: Use the array implementation of a stack.)
10.3-5
Let L be a doubly linked list of length n stored in arrays key, pre�, and next of
length m. Suppose that these arrays are managed by A LLOCATE -O BJECT and
F REE -O BJECT procedures that keep a doubly linked free list F . Suppose further
that of the m items, exactly n are on list L and m n are on the free list. Write
a procedure C OMPACTIFY-L IST .L; F / that, given the list L and the free list F ,
moves the items in L so that they occupy array positions 1; 2; : : : ; n and adjusts the
free list F so that it remains correct, occupying array positions n C1; n C2; : : : ; m.
The running time of your procedure should be ‚.n/, and it should use only a
constant amount of extra space. Argue that your procedure is correct.