0% found this document useful (0 votes)
2 views

Implementing pointers and objects

The document discusses methods for implementing pointers and objects in programming languages that lack explicit pointer data types, focusing on linked data structures. It describes multiple-array and single-array representations of objects, along with procedures for allocating and freeing objects in a doubly linked list. Additionally, it includes exercises related to these implementations, emphasizing the efficiency of the discussed operations.

Uploaded by

kunalrastogi13
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Implementing pointers and objects

The document discusses methods for implementing pointers and objects in programming languages that lack explicit pointer data types, focusing on linked data structures. It describes multiple-array and single-array representations of objects, along with procedures for allocating and freeing objects in a doubly linked list. Additionally, it includes exercises related to these implementations, emphasizing the efficiency of the discussed operations.

Uploaded by

kunalrastogi13
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

10.

3 Implementing pointers and objects 241

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.

10.3 Implementing pointers and objects

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.

A multiple-array representation of objects


We can represent a collection of objects that have the same attributes by using an
array for each attribute. As an example, Figure 10.5 shows how we can implement
the linked list of Figure 10.3(a) with three arrays. The array key holds the values
of the keys currently in the dynamic set, and the pointers reside in the arrays next
and pre�. For a given array index x, the array entries keyŒx�, nextŒx�, and pre�Œx�
represent an object in the linked list. Under this interpretation, a pointer x is simply
a common index into the key, next, and pre� arrays.
In Figure 10.3(a), the object with key 4 follows the object with key 16 in the
linked list. In Figure 10.5, key 4 appears in keyŒ2�, and key 16 appears in keyŒ5�,
and so nextŒ5� D 2 and pre�Œ2� D 5. Although the constant NIL appears in the next
242 Chapter 10 Elementary Data Structures

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.

A single-array representation of objects


The words in a computer memory are typically addressed by integers from 0
to M  1, where M is a suitably large integer. In many programming languages,
an object occupies a contiguous set of locations in the computer memory. A pointer
is simply the address of the first memory location of the object, and we can address
other memory locations within the object by adding an offset to the pointer.
We can use the same strategy for implementing objects in programming envi-
ronments that do not provide explicit pointer data types. For example, Figure 10.6
shows how to use a single array A to store the linked list from Figures 10.3(a)
and 10.5. An object occupies a contiguous subarray AŒj : : k�. Each attribute of
the object corresponds to an offset in the range from 0 to k  j , and a pointer to
the object is the index j . In Figure 10.6, the offsets corresponding to key, next, and
pre� are 0, 1, and 2, respectively. To read the value of i:pre�, given a pointer i, we
add the value i of the pointer to the offset 2, thus reading AŒi C 2�.
The single-array representation is flexible in that it permits objects of different
lengths to be stored in the same array. The problem of managing such a heteroge-
neous collection of objects is more difficult than the problem of managing a homo-
geneous collection, where all objects have the same attributes. Since most of the
data structures we shall consider are composed of homogeneous elements, it will
be sufficient for our purposes to use the multiple-array representation of objects.
10.3 Implementing pointers and objects 243

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.

Allocating and freeing objects


To insert a key into a dynamic set represented by a doubly linked list, we must al-
locate a pointer to a currently unused object in the linked-list representation. Thus,
it is useful to manage the storage of objects not currently used in the linked-list
representation so that one can be allocated. In some systems, a garbage collec-
tor is responsible for determining which objects are unused. Many applications,
however, are simple enough that they can bear responsibility for returning an un-
used object to a storage manager. We shall now explore the problem of allocating
and freeing (or deallocating) homogeneous objects using the example of a doubly
linked list represented by multiple arrays.
Suppose that the arrays in the multiple-array representation have length m and
that at some moment the dynamic set contains n  m elements. Then n objects
represent elements currently in the dynamic set, and the remaining mn objects are
free; the free objects are available to represent elements inserted into the dynamic
set in the future.
We keep the free objects in a singly linked list, which we call the free list. The
free list uses only the next array, which stores the next pointers within the list.
The head of the free list is held in the global variable free. When the dynamic
set represented by linked list L is nonempty, the free list may be intertwined with
list L, as shown in Figure 10.7. Note that each object in the representation is either
in list L or in the free list, but not in both.
The free list acts like a stack: the next object allocated is the last one freed. We
can use a list implementation of the stack operations P USH and P OP to implement
the procedures for freeing and allocating objects, respectively. We assume that the
global variable free used in the following procedures points to the first element of
the free list.
244 Chapter 10 Elementary Data Structures

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

F REE -O BJECT .x/


1 x:next D free
2 free D 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.

You might also like