Chapter 3: Arrays: I. The Array Structure
Chapter 3: Arrays: I. The Array Structure
3: Arrays
The most basic structure for storing and accessing a collection of data is the array.
Arrays can be used to solve a wide range of problems in computer science. Most programming
languages provide this structured data type as a primitive and allow for the creation of arrays
with multiple dimensions.
The array is probably the most widely used data structure; in some languages it is even
the only one available. An array consists of components which are all of the same type, called
its base type; it is therefore called a homogeneous structure. The array is a random-access
structure, because all components can be selected at random and are equally quickly accessible.
In order to denote an individual component, the name of the entire structure is augmented by
the index selecting the component. This index is to be an integer between 0 and n-1, where n is
the number of elements, the size, of the array.
TYPE T = ARRAY n OF T0
Examples
TYPE Row = ARRAY 4 OF REAL
TYPE Card = ARRAY 80 OF CHAR
TYPE Name = ARRAY 32 OF CHAR
A particular value of a variable
VAR x: Row
with all components satisfying the equation xi = 2−i, may be visualized as shown in Figure 3.
11
Figure 3 Array of type Row with xi = 2−i.
12
VAR a: ARRAY N OF INTEGER
sum:= 0;
FOR i:= 0 TO N-1 DO sum:= a[i] + sum END
k:= 0; max:= a[0];
FOR i:= 1 TO N-1 DO
IF max < a[i] THEN k:= i; max:= a[k] END
END.
In a further example, assume that a fraction f is represented in its decimal form with k-1 digits,
i.e., by an array d such that
f=∑ ∗ or
f= + 10 ∗ + 100 ∗ + . . . + ∗ 10
Now assume that we wish to divide f by 2. This is done by repeating the familiar division
operation for all k-1 digits di, starting with i=1. It consists of dividing each digit by 2 taking
into account a possible carry from the previous position, and of retaining a possible remainder
r for the next position:
: = 10 ∗ + [ ];
[ ]: = 2;
:= 2
This algorithm is used to compute a table of negative powers of 2. The repetition of halving to
compute 2−1, 2−2, ..., 2−N is again appropriately expressed by a FOR statement, thus leading to
a nesting of two FOR statements.
PROCEDURE Power(VAR W: Texts.Writer; N: INTEGER);
(*compute decimal representation of negative powers of 2*)
VAR i, k, r: INTEGER;
d: ARRAY N OF INTEGER;
BEGIN
FOR k := 0 TO N-1 DO
Texts.Write(W, "."); r := 0;
FOR i := 0 TO k-1 DO
r := 10*r + d[i]; d[i] := r DIV 2; r := r MOD 2;
Texts.Write(W, CHR(d[i] + ORD("0")))
END ;
d[k] := 5; Texts.Write(W, "5"); Texts.WriteLn(W)
END
END Power.
The resulting output text for N = 10 is
.5
.25
.125
.0625
.03125
.015625
.0078125
.00390625
.001953125
.0009765625
13
II. The importance of arrays
You will notice the array structure looks very similar to list structure. That's because the
two structures are both sequences that are composed of multiple sequential elements that can
be accessed by position. But there are two major differences between the array and the list.
First, an array has a limited number of operations, which commonly include those for array
creation, reading a value from a specific element, and writing a value to a specific element. The
list, on the other hand, provides a large number of operations for working with the contents of
the list. Second, the list can grow and shrink during execution as elements are added or removed
while the size of an array cannot be changed after it has been created.
You may be wondering, if the list structure is a mutable sequence type, why are we
bothering to discuss the array structure, much less plan to implement an abstract data type for
working with arrays? The short answer is that both structures have their uses. There are many
problems that only require the use of a basic array in which the number of elements is known
beforehand and the flexible set of operations available with the list is not needed.
The array is best suited for problems requiring a sequence in which the maximum
number of elements are known up front, whereas the list is the better choice when the size of
the sequence needs to change after it has been created. As you will learn later in the chapter, a
list contains more storage space than is needed to store the items currently in the list. This extra
space, the size of which can be up to twice the necessary capacity, allows for quick and easy
expansion as new items are added to the list. But the extra space is wasteful when using a list
to store a fixed number of elements. For example, suppose we need a sequence structure with
100; 000 elements. We could create a list with the given number of elements
using the replication operator:
values = [ None ] * 100000
But underneath, this results in the allocation of space for up to 200,000 elements, half of which
will go to waste. In this case, an array would be a better choice. The decision as to whether an
array or list should be used is not limited to the size of the sequence structure. It also depends
on how it will be used. The list provides a large set of operations for managing the items
contained in the list. Some of these include inserting an item at a specific location, searching
for an item, removing an item by value or location, easily extracting a subset of items, and
sorting the items. The array structure, on the other hand, only provides a limited set of
operations for accessing the individual elements comprising the array. Thus, if the problem at
hand requires these types of operations, the list is the better choice.
14
length (): Returns the length or number of elements in the array.
getitem ( index ): Returns the value stored in the array at element position index. The
index argument must be within the valid range. Accessed using the subscript operator.
setitem ( index, value ): Modi_es the contents of the array element at position index to
contain value. The index must be within the valid range. Accessed using the subscript
operator.
clearing( value ): Clears the array by setting every element to value.
iterator (): Creates and returns an iterator that can be used to traverse the elements of
the array.
Some computer scientists consider the array a physical structure and not an abstraction since
arrays are implemented at the hardware level. But remember, there are only three basic
operations available with the hardware-implemented array. As part of our Array ADT, we have
provided for these operations but have also included an iterator and operations for obtaining the
size of the array and for setting every element to a given value. In this case, we have provided
a higher level of abstraction than that provided by the underlying hardware-implemented array.
15