Unit 2
Unit 2
ARRAYS
CHAPTER 2 1
● An array is a finite, ordered and collection of homogeneous data
elements.
● Array is finite because it contains only limited no of elements
● It is ordered as all the elements are stored one by one in contiguous
locations of computer memory in a linear ordered fashion.
● All the elements of an array are of the same data type only and hence it
is termed as collection of homogeneous elements.
● An array is known as linear data structure because all elements of the
array are stored in a linear order.
● It is generally a built-in data type in all programming languages.
Terminologies
● Type-kind of data type
st
● Base-memory address location where 1 element in a array is located
data structure
For each index, there is a value associated with
that index.
representation (possible)
implemented by using consecutive memory.
CHAPTER 2 3
● A fixed array - size or length is determined when the
array is created and/or allocated.[1]
● A dynamic array is a random access, variable-size list
data structure that allows elements to be added or
removed.
● It is supplied with standard libraries in many modern
programming languages.
● Dynamic arrays overcome a limit of static arrays, which
have a fixed capacity that needs to be specified at
allocation.[2]
●
CHAPTER 2 4
Structure Array is
objects: A set of pairs <index, value> where for each value of index
there is a value from the set item. Index is a finite ordered set of one or
more dimensions, for example, {0, … , n-1} for one dimension,
{(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)} for two dimensions,
etc.
Functions:
for all A ∈ Array, i ∈ index, x ∈ item, j, size ∈ integer
Array Create(j, list) ::= return an array of j dimensions where list is a
j-tuple whose ith element is the size of the
ith dimension. Items are undefined.
Item Retrieve(A, i) ::= if (i ∈ index) return the item associated with
index value i in array A
else return error
Array Store(A, i, x) ::= if (i in index)
return an array that is identical to array
A except the new pair <i, x> has been
inserted else return error
end array
*Structure 2.1: Abstract Data Type Array ( p.50)
CHAPTER 2 5
Arrays in C
int list[5], *plist[5];
list[5]: five integers
list[0], list[1], list[2], list[3], list[4]
*plist[5]: five pointers to integers
plist[0], plist[1], plist[2], plist[3], plist[4]
implementation of 1-D array
•Compiler allocates 5 consecutive memory locations for the above
declaration
•Each memory location is large enough to hold a single integer
•Address of the first element list[0] is called the base address
•If the size of an integer on your machine is denoted by sizeof(int)
then memory address can be written as α + i*sizeof(int)
list[0] base address = α
list[1] α + 1*sizeof(int)
list[2] α + 2*sizeof(int)
list[3] α + 3*sizeof(int)
list[4] α + 4*sizeof(int)
CHAPTER 2 6
● Compare int *list1 and int list2[5] in C.
CHAPTER 2 7
● Assume that we have the following declaration
int one[] = {0, 1, 2, 3, 4};
Goal: print out address and value
● For ex : Write a function that prints out both the address of the
ith element of this array and the value found at this address
● The program print1 uses pointer arthimetic
● The function is invoked as print1(&one[0],5)
● The address of the ith element is simply ptr+i
● To obtain the value of the ith element we use the dereferencing
operator, *.
● Thus, *(ptr+i) indicates that we want the contents of the ptr+i
position rather than the address
CHAPTER 2 8
Example: 1-dimension array addressing
CHAPTER 2 9
call print1(&one[0], 5)
CHAPTER 2 10
CHAPTER 2 11
POLYNOMIALS
● Arrays are not only data structures in their own right, it can also be used
to implement other abstract data types.
● For instance, let us consider one of the simplest and most commonly
found data structures: the ordered, or linear, list.
● Examples include
– Days of the week: (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday,
Saturday)
– Values in a deck of cards: (Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King)
– Floors of a building: (basement, lobby, mezzanine, first, second)
– Years the United States fought in World War II: (1941, 1942, 1943, 1944,
1945)
– Years Switzerland fought in World War II: ()
CHAPTER 2 19
case 1: d =
Attach(d, Coef (a, Lead_Exp(a)), Lead_Exp(a));
a = Remove(a, Lead_Exp(a));
}
}
insert any remaining terms of a or b into d
CHAPTER 2 20
Data structure 2: use one global array to store all polynomials
A(X)=2X1000+1
B(X)=X4+10X3+3X2+1 *Figure 2.2: Array representation of two polynom
starta finisha startb (p.63) finishb avail
coef
exp
0 1 2 3 4 5 6
specification representation
poly <start, finish>
A <0,1>
B <2,5>
CHAPTER 2 21
● In this representation, coefficients are stored in the order of
decreasing exponents, such that a.coef[i] is the coefficient of x
(to the power of) n-i provided a term with exponent n-i exists;
otherwise, a . coef [i] = 0.
● Although this representation leads to very simple algorithms for
most of the operations, it wastes a lot of space.
● For instance, if a.degree<<MAX-DEGREE, then most of the
positions in a.coef [MAX-DEGREE] is not needed.
● The same argument applies if the polynomial is sparse, that is,
the number of terms with nonzero coefficient is small relative to
the degree of the polynomial.
● To preserve space, an alternate representation is devised which
uses only one global array, terms, to store all polynomials.
● The C declarations needed are:
● The index of the first term of A and B is given by starta and startb, respectively,
while finisha and finishb give the index of the last term of A and B.
● The index of the next free location in the array is given by avail.
starta = 0, finisha = 1, startb = 2, finishb = 5, and avail = 6.
● This representation does not impose any limit on the number of polynomials
which is placed in the terms.
● The only stipulation is that the total number of nonzero terms must be no more
than MAX-TERMS.
● It is worth pointing out the difference between our specification and our
representation.
● Specification used poly to refer to a polynomial, and representation translated
poly into a <start, finish > pair.
● Therefore, to use A (x) we must pass in starta and finisha.
● Any polynomial A that has n nonzero terms has starta and finisha such that
finisha = starta + n - 1.
● This representation certainly solves the problem of many zero terms since A (x) =
2x to the power1000 +1 uses only six units of storage
one for starta, one for finisha, two for the coefficients, and two for the exponents.
● However, when all the terms are nonzero, the current representation requires
about twice as much space as the first one.
● Unless we know before hand that each of our polynomials has few zero terms,
this current representation is probably better.
● C function that adds two polynomials, A and B, represented as above to obtain
D = A + B.
● To produce D(x), padd (Program 2.5) adds A (x) and B(x) term by term.
● Starting at position avail, attach (Program 2.6) places the terms of D into the
a array, terms.
● If there is not enough space in terms to accommodate D, an error message is
printed to the standard error device and exit the program with an error condition.
storage requirements: start, finish, 2*(finish-start+1)
nonparse: twice as much as (1)
when all the items are nonzero
CHAPTER 2 25
Add two polynomials: D = A + B
void padd (int starta, int finisha, int startb, int finishb,
int * startd, int *finishd)
{
/* add A(x) and B(x) to obtain D(x) */
float coefficient;
*startd = avail;
while (starta <= finisha && startb <= finishb)
switch (COMPARE(terms[starta].expon,
terms[startb].expon)) {
case -1: /* a expon < b expon */
attach(terms[startb].coef, terms[startb].expon);
startb++
break;
CHAPTER 2 26
case 0: /* equal exponents */
coefficient = terms[starta].coef +
terms[startb].coef;
if (coefficient)
attach (coefficient, terms[starta].expon);
starta++;
startb++;
break;
case 1: /* a expon > b expon */
attach(terms[starta].coef, terms[starta].expon);
starta++;
}
CHAPTER 2 27
/* add in remaining terms of A(x) */
for( ; starta <= finisha; starta++)
attach(terms[starta].coef, terms[starta].expon);
/* add in remaining terms of B(x) */
for( ; startb <= finishb; startb++)
attach(terms[startb].coef, terms[startb].expon);
*finishd =avail -1;
}
Analysis: O(n+m)
where n (m) is the number of nonzeros in A(B).
CHAPTER 2 28
void attach(float coefficient, int exponent)
{
/* add a new term to the polynomial */
if (avail >= MAX_TERMS) {
fprintf(stderr, “Too many terms in the polynomial\n”);
exit(1);
}
terms[avail].coef = coefficient;
terms[avail++].expon = exponent;
}
*Program 2.6:Function to add a new term (p.65)
Problem: Compaction is required
when polynomials that are no longer needed.
(data movement takes time.)
CHAPTER 2 29
● Analysis of padd-. The number of nonzero terms in A and in
B B are the most important factors in the time complexity.
● Therefore, let tn and n be the number of nonzero terms in
A A and B, respectively.
● If tn > 0 and n > 0, the while loop is entered. Each t
e iteration of the loop requires 0(1) time.
● At each iteration, increment the value of starta or
a startb or both.
● Since the iteration terminates when either starta or startb
exceeds finisha or finishb, respectively, the number of iterations
is bounded by m + n - 1. This worst case occurs when:
●
● The time for the remaining two loops is bounded by O(n + m)
because we cannot iterate the first loop more than m times and
the second more than n times.
● So, the asymptotic computing time of this algorithm is O(n
+m).One of the problems with the current representation is that,
while creating polynomials, avail is incremented until it equals
MAX-TERMS.
● When this occurs, must we quit?
● Given the current representation, we must unless there are some
polynomials that are no longer needed.
● A compaction function is written which would remove the
unnecessary polynomials and create a large, continuous
available space at one end of the array.
● However, this requires data movement which takes time.
● In addition, we also must change the start and end indices for
each polynomial moved (i.e) the values of starti and finishi is
CHAPTER 2 31
changed for all polynomials moved.
Sparse Matrix
row1
row2
row3
row4
row5
5*3 6*6
(a) 15/15 (b) 8/36
CHAPTER 2 33
Sparse_Matrix Transpose(a) ::=
return the matrix produced by interchanging
the row and column value of every triple.
Sparse_Matrix Add(a, b) ::=
if the dimensions of a and b are the same
return the matrix produced by adding
corresponding items, namely those with
identical row and column values.
else return error
Sparse_Matrix Multiply(a, b) ::=
if number of columns in a equals number of
rows in b
return the matrix d produced by multiplying
a by b according to the formula: d [i] [j] =
(a[i][k]•b[k][j]) where d (i, j) is the (i,j)th
element
else return error.
CHAPTER 2 34
* Structure 2.3: Abstract data type Sparse-Matrix (p.68)
(1) Represented by a two-dimensional array.
Sparse matrix wastes space.
(2) Each element is characterized by <row, col, value>.
row col value row col value
# of rows (columns)
# of nonzero terms
a[0] 6 6 8 b[0] 6 6 8
[1] 0 0 15 [1] 0 0 15
[2] 0 3 22 [2] 0 4 91
[3] 0 5 -15 transpose [3] 1 1 11
[4] 1 1 11 [4] 2 1 3
[5] 1 2 3 [5] 2 5 28
[6] 2 3 -6 [6] 3 0 22
[7] 4 0 91 [7] 3 2 -6
[8] 5 2 28 [8] 5 0 -15
(a) (b)
row, column in ascending order
*Figure 2.4:Sparse matrix and its transpose stored as triples (p.69)
CHAPTER 2 35
Sparse_matrix Create(max_row, max_col) ::=
* (P.69)
CHAPTER 2 36
Transpose a Matrix
elements
b[currentb].row = a[j].col;
b[currentb].col = a[j].row;
b[currentb].value = a[j].value;
currentb++
}
}
}
* Program 2.7: Transpose of a sparse matrix (p.71)
Solution:FT
Determine the number of elements in each column of
the original matrix.
==>
Determine the starting positions of each row in the
transpose matrix.
CHAPTER 2 40
a[0] 6 68
a[1] 0 015
a[2] 0 322
a[3] 0 5-15
a[4] 1 111
a[5] 1 23
a[6] 2 3-6
a[7] 4 091
a[8] 5 228
[0] [1] [2] [3] [4] [5]
row_terms = 2 1 2 2 0 1
starting_pos = 1 3 4 6 8 8
CHAPTER 2 41
● The O{columns • elements) time for our transpose function becomes
O(columns.columns.elements) when the number of elements is of the
order columns.rows.
● Perhaps, to conserve space, we have traded away too much time.
● Actually, we can create a much better algorithm by using a little more
storage.
● In fact, we can transpose a matrix represented as a sequence of triples
in O{columns + elements) time.
● This algorithm, fast-transpose (Program 2.8), proceeds by first
determining the number of elements in each column of the original
matrix.
● This gives us the number of elements in each row of the transpose
matrix.
● From this information, we can determine the starting position of each
row in the transpose matrix.
● We now can move the elements in the2 original matrix one by one into42
CHAPTER
their correct position in the transpose matrix.
void fast_transpose(term a[ ], term b[ ])
{
/* the transpose of a is placed in b */
int row_terms[MAX_COL], starting_pos[MAX_COL];
int i, j, num_cols = a[0].col, num_terms = a[0].value;
b[0].row = num_cols; b[0].col = a[0].row;
b[0].value = num_terms;
if (num_terms > 0){ /*nonzero matrix*/
for (i = 0; i < num_cols; i++)
columns row_terms[i] = 0;
for (i = 1; i <= num_terms; i++)
elements
row_term [a[i].col]++
starting_pos[0] = 1;
for (i =1; i < num_cols; i++)
columns starting_pos[i]=starting_pos[i-1] +row_terms [i-1];
CHAPTER 2 43
for (i=1; i <= num_terms, i++) {
j = starting_pos[a[i].col]++;
elements b[j].row = a[i].col;
b[j].col = a[i].row;
b[j].value = a[i].value;
}
}
}
*Program 2.8:Fast transpose of a sparse matrix
CHAPTER 2 45
*Figure 2.5:Multiplication of two sparse matrices (p.73)
An Example
A= 1 0 2 B =3 0 2
-1 4 6 -1 0 0
0 0 5
2 3 5 3 3 4
0 0 1 0 0 3
0 2 2 0 2 2
1 0 -1 1 0 -1
1 1 4 2 2 5
1 2 6 (0,0)
(0,2)
BT = 3 -1 0 3 3 (1,0)
4
0 0 0 0 0 3
2 0 5 0 1 -1 (1,2)
2 0 2
2 2 5
CHAPTER 2 46
General Case
dij=ai0*b0j+ai1*b1j+…+ai(n-1)*b(n-1)j
a本來依i成群,經轉置後,b也依j成群。
a Sa d Sd
b Sb e Se
c Sc f Sf
g Sg
CHAPTER 2 47
void mmult (term a[ ], term b[ ], term d[ ] )
/* multiply two sparse matrices */
{
int i, j, column, totalb = b[].value, totald = 0;
int rows_a = a[0].row, cols_a = a[0].col,
totala = a[0].value; int cols_b = b[0].col,
int row_begin = 1, row = a[1].row, sum =0;
int new_b[MAX_TERMS][3];
if (cols_a != b[0].row){
fprintf (stderr, “Incompatible matrices\n”);
exit (1);
}
CHAPTER 2 48
fast_transpose(b, new_b); cols_b + totalb
/* set boundary condition */
a[totala+1].row = rows_a;
new_b[totalb+1].row = cols_b;
new_b[totalb+1].col = 0;
for (i = 1; i <= totala; ) { at most rows_a times
column = new_b[1].row;
for (j = 1; j <= totalb+1;) {
/* mutiply row of a by column of b */
if (a[i].row != row) {
storesum(d, &totald, row, column, &sum);
i = row_begin;
for (; new_b[j].row == column; j++)
;
column =new_b[j].row
}
CHAPTER 2 49
else switch (COMPARE (a[i].col, new_b[j].col)) {
case -1: /* go to next term in a */
i++; break;
case 0: /* add terms, go to next term in a and b */
sum += (a[i++].value * new_b[j++].value);
break;
case 1: /* advance to next term in b*/
j++
}
} /* end of for j <= totalb+1 */
for (; a[i].row == row; i++)
;
row_begin = i; row = a[i].row;
} /* end of for i <=totala */
d[0].row = rows_a;
d[0].col = cols_b; d[0].value = totald;
}
*Praogram 2.9: Sparse matrix multiplication (p.75)
CHAPTER 2 50
Analyzing the algorithm
cols_b * termsrow1 + totalb +
cols_b * termsrow2 + totalb +
…+
cols_b * termsrowp + totalb
= cols_b * (termsrow1 + termsrow2 + … + termsrowp) +
rows_a * totalb
= cols_b * totala + row_a * totalb
CHAPTER 2 51
Compared with matrix multiplication using array
for (i =0; i < rows_a; i++)
for (j=0; j < cols_b; j++) {
sum =0;
for (k=0; k < cols_a; k++)
sum += (a[i][k] *b[k][j]);
d[i][j] =sum;
}
O(rows_a * cols_a * cols_b) vs.
O(cols_b * total_a + rows_a * total_b)
optimal case: total_a < rows_a * cols_a
total_b < cols_a * cols_b
worse case: total_a --> rows_a * cols_a, or
total_b --> cols_a * cols_b
CHAPTER 2 52
void storesum(term d[ ], int *totald, int row, int column,
int *sum)
{
/* if *sum != 0, then it along with its row and column
position is stored as the *totald+1 entry in d */
if (*sum)
if (*totald < MAX_TERMS) {
d[++*totald].row = row;
d[*totald].col = column;
d[*totald].value = *sum;
}
else {
fprintf(stderr, ”Numbers of terms in product
exceed %d\n”, MAX_TERMS);
exit(1);
}
}
CHAPTER 2 53
Program 2.10: storsum function
Video Links
CHAPTER 2 54