CHAPTER 2


ARRAYS AND STRUCTURES

  All the programs in this file are selected from
           Ellis Horowitz, Sartaj Sahni, and Susan Anderson-Freed
           “Fundamentals of Data Structures in C”,
           Computer Science Press

                  CHAPTER 2                        1
Arrays
Array( 数组 ): a set of index( 索引 ) and value( 值 )
             Array:=<index, value>

data structure
        For each index, there is a value associated
with
        that index.

representation (possible)
       implemented by using consecutive memory.



               CHAPTER 2                    2
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                                3
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
      list[0]       base address = α
      list[1]       α + sizeof(int)
      list[2]       α + 2*sizeof(int)
      list[3]       α + 3*sizeof(int)
      list[4]       α + 4*size(int)

                 CHAPTER 2                        4
Arrays in C (Continued)
Compare int *list1 and int list2[5] in C.

        Same: list1 and list2 are pointers.
        Difference: list2 reserves five locations.

Notations:
       list2 - a pointer to list2[0]
       (list2 + i) - a pointer to list2[i]       (&list2[i])
       *(list2 + i) - list2[i]




               CHAPTER 2                     5
Example: 1-dimension array addressing
                 Address                   Contents
            int one[] = {0, 1, 2, 3, 4};
                 1228 out address and value
            Goal: print
                                         0
                   1230
    void print1(int *ptr, int rows)                   1
    {
                   1232                               2
    /* print out a one-dimensional array using a pointer */
            int i; 1234                               3
            printf(“Address Contentsn”);
                   1236
            for (i=0; i < rows; i++)                  4
                       printf(“%8u%5dn”, ptr+i, *(ptr+i));
            printf(“n”);
    }     *Figure 2.1: One- dimensional array addressing (p.53)

   call print1(&one[0], 5)
                   CHAPTER 2                      6
Structures (records)

   struct {
              char name[10];
              int age;
              float salary;
              } person;

   strcpy(person.name, “james”);
   person.age=10;
   person.salary=35000;



     CHAPTER 2                     7
Create structure data type
  typedef struct human_being {
         char name[10];
         int age;
         float salary;
         };

  or

  typedef struct {
         char name[10];
         int age;
         float salary
         } human_being;

  human_being person1, person2;
     CHAPTER 2                  8
Unions
Similar to struct, but only one field is active.
Example: Add fields for male and female.
typedef struct {
       enum tag_field {female, male} sex;
       union {
                int children;
                int beard;
                } u;
       } sex_type;
typedef struct {
       char name[10]; human_being person1, person2;
       int age;            person1.sex_info.sex=male;
       float salary;       person1.sex_info.u.beard=FALSE;
       date dob;
       sex_type sex_info;
       } human_being; 2
               CHAPTER                       9
Self-Referential Structures
 One or more of its components is a pointer to itself.

 typedef         struct {   Construct a list with three nodes
        char data;          item1.link=&item2;
        list *link;         item2.link=&item3;
        } list;             malloc: obtain a node

 list item1, item2, item3;
 item1.data=‘a’;           a       b              c
 item2.data=‘b’;
 item3.data=‘c’;
 item1.link=item2.link=item3.link=NULL;
             CHAPTER 2                     10
Ordered List Examples
linear list:
 ordered list: (item1, item2, item3, …, itemn)

 (MONDAY, TUEDSAY, WEDNESDAY, THURSDAY, FRIDAY,
  SATURDAYY, SUNDAY)
 (2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace)
 (1941, 1942, 1943, 1944, 1945)
 (a1, a2, a3, …, an-1, an)




                        CHAPTER 2                        11
Operations on Ordered List
 Get the length of the list (n).
 Read the items from left to right (or right to left).
 Retrieve the i’th element.
 Store a new value into the i’th position.
 Insert a new element at the position i , causing
  elements numbered i, i+1, …, n to become numbered
  i+1, i+2, …, n+1
 Delete the element at position i , causing elements
  numbered i+1, …, n to become numbered i, i+1, …, n-
  1 array (sequential mapping)? (1)~(4) O (5)~(6) X


                    CHAPTER 2                   12
Polynomials A(X)=3X20+2X5+4, B(X)=X4+10X3+3X2+1
Structure Polynomial is
objects: p ( x ) = a1 x e1 + ... + an x en; a set of ordered pairs of <ei,ai> where
ai in Coefficients and ei in Exponents, ei are integers >= 0

functions:
for all poly, poly1, poly2  Polynomial, coef Coefficients, expon Exponents

Polynomial Zero( )                     ::= return the polynomial,
                                             p(x) = 0
Boolean IsZero(poly)                   ::= if (poly) return FALSE
                                              else return TRUE
Coefficient Coef(poly, expon)          ::= if (expon  poly) return its
                                              coefficient else return Zero

Exponent Lead_Exp(poly)                 ::= return the largest exponent in poly

Polynomial Attach(poly,coef, expon) ::= if (expon  poly) return error
                                           else return the polynomial poly
                                           with the term <coef, expon>
                                           inserted
                           CHAPTER 2                          13
Polynomial Remove(poly, expon)             ::= if (expon  poly)
                                        return the polynomial poly
                                         with the term whose
                                        exponent is expon deleted
                                                else return error
Polynomial Single Mult(poly, coef, expon) ::= return the polynomial
                                                   poly • coef • xexpon
Polynomial Add(poly1, poly2)              ::= return the polynomial
                                                   poly1 +poly2
Polynomial Mult(poly1, poly2)            ::= return the polynomial
                                                     poly1 • poly2

  End Polynomial
   *Structure 2.2:Abstract data type Polynomial (p.61)


                           CHAPTER 2                     14
Polynomial Addition
A(X)=2X8+1, B(X)=X4+10X3+3X2+1




Exp 8        7      6      5    4   3    2        1   0
A(X 2        0      0      0    0   0    0        0   1
)
B(X 0        0      0      0    1   10   3        0   1
)


      Coefficient       CHAPTER 2            15
Polynomial Addition(cont.)
            data structure 1:                   #define MAX_DEGREE 101
                                                typedef struct {
                                                         int degree;
                                                         float coef[MAX_DEGREE];
/* d =a + b, where a, b, and d are polynomials */        } polynomial;
d = Zero( )
while (! IsZero(a) && ! IsZero(b)) do {             case 1: d =
  switch COMPARE (Lead_Exp(a), Lead_Exp(b))                    Attach(d, Coef (a,
     {                                                           Lead_Exp(a)),
   case -1: d =                                     Lead_Exp(a));
        Attach(d, Coef (b, Lead_Exp(b)),                       a = Remove(a,
                           Lead_Exp(b));            Lead_Exp(a));
        b = Remove(b, Lead_Exp(b));                        }
        break;
                                                       }
    case 0: sum = Coef (a, Lead_Exp (a)) + Coef
                    ( b, Lead_Exp(b));              insert any remaining terms
       if (sum) {                                   of a or b into d
           Attach (d, sum, Lead_Exp(a));    *Program 2.4 :Initial version of padd function(p.62)
           a = Remove(a , Lead_Exp(a));      Advantage: easy implementation
           b = Remove(b , Lead_Exp(b));
           }                                 Disadvantage: waste space when
                                CHAPTER 2                          16
        break;                               sparse
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 polynomials
                                    (p.63)
          starta finisha startb                       finishb avail



  coef        2        1       1        10       3       1
   exp     1000        0       4         3       2       0
              0        1        2            3   4         5         6
 specification                representation
 poly                         <start, finish>
 A                            <0,     1>
 B                    CHAPTER <2,
                              2       5>      17
storage requirements: start, finish, 2*(finish-start+1)
nonparse:      twice as much as (1)
               when all the items are nonzero



MAX_TERMS 100 /* size of terms array */
typedef struct {
          float coef;
          int expon;
          } polynomial;
polynomial terms[MAX_TERMS];
int avail = 0;
 *(p.62)


                    CHAPTER 2                    18
Add two polynomials: D = A + B
void padd (int starta, int finisha, int startb,      if (coefficient)
int finishb,int * startd, int *finishd)                    attach (coefficient,
{ /* add A(x) and B(x) to obtain D(x) */             terms[starta].expon);
    float coefficient;                                     starta++;
   *startd = avail;                                        startb++;
   while (starta <= finisha && startb <=                   break;
           finishb)                                  case 1: /* a expon > b expon */
     switch COMPARE(terms[starta].expon,                      attach(terms[starta].coef,
                            terms[startb].expon))                   terms[starta].expon);
{                                                             starta++;
      case -1: /* a expon < b expon */               }
                                                     /* add in remaining terms of A(x) */
            attach(terms[startb].coef,
                                                     for( ; starta <= finisha; starta++)
           terms[startb].expon);
                                                         attach(terms[starta].coef,
            startb++
                                                     terms[starta].expon);
            break;                                   /* add in remaining terms of B(x) */
  case 0: /* equal exponents */                    for( ; startb <= finishb; startb++)
        coefficient = terms[starta].coef+             attach(terms[startb].coef,
                                terms[startb].coef terms[startb].expon);
Analysis:            O(n+m)                        *finishd =avail -1;
                     where n (m) is the 2
                              CHAPTER           number of nonzeros in A(B).
                                                   }
                                                                            19
void attach(float coefficient, int exponent)
{
/* add a new term to the polynomial */
    if (avail >= MAX_TERMS) {
       fprintf(stderr, “Too many terms in the polynomialn”);
       exit(1);
      }
      terms[avail].coef = coefficient;
      terms[avail++].expon = exponent;
}
     *Program 2.6:Function to add anew term (p.65)

    Problem:            Compaction is required
                        when polynomials that are no longer needed.
                        (data movement takes time.)
                          CHAPTER 2                  20
Sparse Matrix


                              col1
                               15     col2 col3 22 0 −col6
                                       0 0 col4 col5 15
                       row0    0     11 3  0 0         0
                       row1
                                                        
                               0      0 0 −6 0         0
                       row2                             
                               0      0 0  0 0         0
                       row3   91      0 0  0 0         0
                                                        
                       row4
                               0
                                      0 28 0 0         0
                                                         
                       row5
                 5*3                                          6*6
          (a)    15/15                    (b)    8/36

*Figure 2.3:Two matrices               sparse matrix
                                      data structure?

            CHAPTER 2                           21
SPARSE MATRIX ABSTRACT DATA TYPE

Structure Sparse_Matrix is
objects: a set of triples, <row, column, value>,
          where row and column are integers and form a unique
          combination,and value comes from the set item.
functions:
  for all a, b ∈ Sparse_Matrix, x  item, i, j, max_col,
  max_row  index

Sparse_Marix Create(max_row, max_col)

::= return a Sparse_matrix that can hold up to
    max_items = max _row  max_col and
    whose maximum row size is max_row and
    whose maximum column size is max_col.



                  CHAPTER 2                     22
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                          23
     * 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                                         row col value
            a[0] 6                                               b[0] 6                                                c[0] 6
      6  8                                                 6  8                                                 6   8
  [1] 0   0 15                                         [1] 0   0 15                                         [1]   0   0 15
 [2] 0   3 22                                         [2] 3   0 22                                         [2]    0   4 91

  [3]            0         5    -15                    [3]        5      0      -15                        [3]        1               1   11

 [4]         1          1      11                     [4]         1     1      11                         [4]         2           1       3
                                          transpose                                      transpose
 [5]         1         2       3                      [5]         2     1      3                           [5]            2           5   28

 [6]         2         3       -6                     [6]         3     2      -6                          [6]            3           0   22

       [7]           4    0         91                      [7]       0    4        91                          [7]           3      2        -6
       [8]           5 (a) 2        28                      [8]       2(b) 5        28                          [8]           5   (c)0        -15

a[0].row ---- the number of rows in a
a[0].col ---- the number of columns in a
a[0].total ---- the total number of nonzero entries in a.
                        CHAPTER 2                                                                    24
row, column in ascending order
Sparse_matrix Create(max_row, max_col) ::=

#define MAX_TERMS 101 /* maximum number of terms +1*/
  typedef struct {
          int col;   # of rows (columns)
          int row;
          int value; # of nonzero terms
          } term;
  term a[MAX_TERMS]


   * (P.69)


              CHAPTER 2               25
Transpose a Matrix

(1) for each row i
        take element <i, j, value> and store it
        in element <j, i, value> of the transpose.

   difficulty: where to put <j, i, value>
        (0, 0, 15) ====> (0, 0, 15)
        (0, 3, 22) ====> (3, 0, 22)
        (0, 5, -15) ====> (5, 0, -15)
         (1, 1, 11) ====> (1, 1, 11)
   Move elements down very often.

(2) For all elements in column j,
        place element <i, j, value> in element <j, i, value>

               CHAPTER 2                     26
void transpose (term a[], term b[])
/* b is set to the transpose of a */                         b[currentb].row = a[j].col;
{                                                            b[currentb].col = a[j].row
   int n, i, j, currentb;                                    b[currentb].value = a[j].value;
   n = a[0].value; /* total number of elements */                       currentb++
   b[0].row = a[0].col; /* rows in b = columns in a */                }
   b[0].col = a[0].row; /*columns in b = rows in a */          }
   b[0].value = n;                                           }
   if (n > 0) {                /*non zero matrix */
       currentb = 1;
       for (i = 0; i < a[0].col; i++)
       /* transpose by columns in a */
            for( j = 1; j <= n; j++)
            /* find elements from the current column */
            if (a[j].col == i) {
           /* element is in current column, add it to b */


* Scan the array “columns” times.
  Program 2.7: Transpose of a sparse matrix (p.71)
                                     ==> O(columns*elements)
 The array has “elements” elements.2
                       CHAPTER                  27
Discussion: compared with 2-D array representation

  O(columns*elements) vs. O(columns*rows)

  elements = columns * rows when nonsparse
  O(columns*columns*rows)

Problem: Scan the array “columns” times.

Solution:
  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                  28
Row     Col   Value                      Row     Col   Value

a[0]   6         6     8                 b[0]       6    6        8
a[1]   0         0     15                b[1]       0    0        15
a[2]   0         3     22                b[2]       0    4        91
a[3]   0         5     -15               b[3]       1    1        11
a[4]   1         1     11                b[4]       2    1        3
a[5]   1         2     3                 b[5]       2    5        28
a[6]   2         3     -6                b[6]       3    0        22
a[7]   4         0     91                b[7]       3    2        -6
a[8]   5         2     28                b[8]       5    0        -15
        Matrix                                Transposed matrix

                          [0] [1] [2] [3] [4] [5]
           row_terms =     2 1 2 2 0 1
           starting_pos = 1 3 4 6 8 8
                         CHAPTER 2                      29
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++)
        row_terms[i] = 0;
     for (i = 1; i <= num_terms; i++)
        row_term [a[i].col]++ ;
      starting_pos[0] = 1;
     for (i =1; i < num_cols; i++)
        starting_pos[i]=starting_pos[i-1] +row_terms [i-1];




                          CHAPTER 2                      30
for (i=1; i <= num_terms, i++) {
                j = starting_pos[a[i].col]++;
                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


Compared with 2-D array representation
        O(columns+elements) vs. O(columns*rows)
elements --> columns * rows
        O(columns+elements) --> O(columns*rows)

Cost: Additional row_terms and starting_pos arrays are required.
      Let the two arrays row_terms and starting_pos be shared.
                     CHAPTER 2                       31
Sparse Matrix Multiplication
Definition: [D]m*p=[A]m*n* [B]n*p
Procedure: Fix a row of A and find all elements in column j
           of B for j=0, 1, …, p-1.

Alternative 1. Scan all of B to find all elements in j.
Alternative 2. Compute the transpose of B.
               (Put all column elements consecutively)

 1 0 0 1 1 1 1 1 1
 1 0 0 0 0 0 = 1 1 1
                    
 1 0 0 0 0 0 1 1 1
                    
                               CHAPTER 2                            32
         *Figure 2.5:Multiplication of two sparse matrices (p.73)
The String Abstract Data Type


  String
  DEFINITION
   String can be denoted as: S= s0,……, sn-1, where si are
   characters taken from the character set of the
   programming language.
  if n = 0, then S is an empty or null string.




                    CHAPTER 2                 33
REPRESENTATION

#define MAX_SIZE 100 /* maximum size of string */
char s [MAX_SIZE ] = { " dog "};
char s [ ] = { " dog "};
char t [MAX_SIZE ] = {"house "};
char t [ ] = {"house "};
s[0]     s[1]     s[2]   s[3]
   d      o        g      n
t[0]     t[1]     t[2]    t[3]   t[4] t[5]
   h      o        u       s      e   n




                    CHAPTER 2             34
structure String is
objects: a finite set of zero or more characters.
Functions: for all s, t String, i, j, m non-negative integers
 String Null(m)            ::=       return a string whose maximum length is m
                                     characters, but is initially set to NULL
                                     we write NULL as ""
 Integer Compare(s,t ) ::=           if s equals t return 0
                                     else if s precedes t return -1
                                            else return 1
 Boolean IsNull( s )       ::=       if ( compare( s, NULL))
                                     return FALSE
                                     else return TRUE
 INTEGER Length (s) ::=              if (COMPARE (s, NULL))
                                     return the number of characters in s
                                     else return 0
 String Concat (s, t ) ::=           if ( COMPARE (t, NULL))
                                     return a string whose elements are those
                                     of s followed by those of t
                                     else return s.
 String Substr (s, i, j ) ::=        if ((j > 0 )&& (i + j -1 ) < length(s))
                                     return the string containing the characters
                                     of s at the position i, i+1, … , i + j -1.
                                     else return NULL
 end String                  CHAPTER 2                              35
〖 example 〗 string insertion
 OPERATIONS ( list )
 Insert string t into string s at position i


#include <string.h>
#define MAX_SIZE 100 /* maximum size of string */
char string1 [MAX_SIZE ] , *s = string1;
char string2 [MAX_SIZE ] , *t = string2;


                   CHAPTER 2               36
〖 example 〗 string insertion
void strnins (char *s, char *t, int i)
{ / * insert string t into string s at position i */
  char string[MAX_SIZE], *temp = string;
  if ( i < 0 && i > strlen ( s ) ) {
        fprintf ( stderr, " position is out bounds  n ");
        exit (1);
  }
  if (!strlen (s ))
        strcpy ( s, t);
  else if (strlen ( t )) {
        strncpy ( temp, s, i);
        strcat ( temp, t) ;
        strcat ( temp, (s + i ));
        strcpy ( s, temp );
  }
}                            CHAPTER 2               37
〖 example 〗 string insertion
     s      a     m       o   b     i       l   e 0

     t      u         t   o 0

   temp    0
          initially
   temp     a 0
          (a) after strncpy ( temp, s ,i)
   temp     a         u   t   o 0
          (b) after strcat ( temp, t)
   temp     a         u   t   o m           o   b   i        l   e 0

          (c) after strcat ( temp, ( s + i ))
                      CHAPTER 2                         38
patter                a      a     b                〖 example 〗 patterm
                                                                matching
                                  j           lastp

no match    a      b     a       b      b     a       a     b    a     a
           start       endmatch                                      lasts

no match    a      b      a      b      b     a       a     b    a     a

                start        endmatch                                lasts

no match    a      b     a       b      b     a       a     b    a     a
                        start         endmatch                       lasts
no match    a      b      a      b      b     a       a     b    a     a

                                start       endmatch                  lasts
no match    a      b      a      b      b     a       a     b    a     a

                                      start       endmatch           lasts
 match      a      b      a      b      b     a       a     b    a     a
                        CHAPTER 2
                              start                       endmatch lasts
                                                                        39
Example: Pattern Matching
int nfind ( char *string, char *pat )
{ /* match the last character of patter first, and then match from
     the beginning */
     int i, j, start = 0;
     int lasts = strlen (string ) -1;
     int lastp = strlen ( pat) -1 ;
     int endmatch = lastp;
     for ( i = 0; endmatch < = lasts; endmatch++, start++) {
       if ( string [endmatch ] == pat [lastp ])
            for ( j = 0; i = start; j < lastp && string [ i ] ==pat [ j ]; i++, j++)
                      ;
            if ( j == lastp )
                      return start; /*successful */
     }
     return -1;
}

    n ----- the length of pat      m ----- the length of string
    the worst case :                              O(n *m)
                                CHAPTER 2                            40
String Pattern Matching: The Knuth-
       Morris-Pratt Algorithm



 Definition:
  If p= p0p1. . .pn-1 is a pattern, then its failure function,
    f, is defined as:
   f(j)= largest k< j such that p0p1. . .pk=
    pj-kpj-k+1. . .pj, if such a k>= 0 exists
         = -1, otherwise


                      CHAPTER 2                   41
 Example
      J         0 1 2 3 4 5 6 7 8 9
      pat       a b c a b c a c a b
      f         -1 -1 -1 0 1 2 3 -1 0 1


  Example
          J       0 1 2 3 4 5 6 7
          pat     a a b a a a a b
          f      -1 0 -1 0 1 1 1 2
                    CHAPTER 2             42
#include <stdio.h>
#include <string.h>
#define max_sring_size 100
#define max_pattern_size 100
int pmatch ( );
void fail ( );
int failure [ max_pattern_size ];
char pat [ max_pattern_size ];
char string [ max_string_size ];


                CHAPTER 2           43
int pmatch ( char *string, char *pat)
{ /* Knuth, Morris, Pratt string matching algorithm, O(strlen(string)) */
   int i = 0, j = 0;
   int lens = strlen ( string );
   int lenp = strlen ( pat);                  Lens=11,lenp = 6

   while ( i < lens && j < lenp ) {
        if (string [ i ] == pat [ j ] ) { i=5,j=5-j=failue[4]+1=4
                i ++; j ++}
        else if ( j == 0 ) i ++;
        else j = failure [ j - 1 ] + 1;
   }
   return (( j == lenp ) ? ( i - lenp ) : -1 );
} j
                                            i

Example
J         0 1 2 3 4 5               string =“a a a a a a a a a a ab”
    pat     a a a a a b
f         -1 0 1 2 3 0
                          CHAPTER 2                    44
computting the failure function O(strlen(pat))
void fail ( (char *pat )
( /* compute the pattern's failure function */
   int n = strlen (pat );
   failure [ 0 ] = -1;
   for ( j = 1; j < n; j ++) {
         i = failure [ j -1 ];
         while ( ( pat [ j ] != pat [ i +1 ] && ( i >= 0))
                    i = failure [ i ];
         if ( pat [ j ] == pat [ i + 1] )
                    failure [ j ] == i + 1;
         else failure [ j ] = -1;
   }
}

   Example
              J      0    1 2 3 4 5    6   7
Example
              pat    a    a b a a a    a   b
              J       0    1 2 3 4     5    6 7 8 9
               f    -1    0 -1 0 1 1   1   2
              pat    a b c a b c a c a b
              f     -1 -1 -1CHAPTER 20 1
                             0 1 2 3 -1                      45

Arrays and structures

  • 1.
    CHAPTER 2 ARRAYS ANDSTRUCTURES All the programs in this file are selected from Ellis Horowitz, Sartaj Sahni, and Susan Anderson-Freed “Fundamentals of Data Structures in C”, Computer Science Press CHAPTER 2 1
  • 2.
    Arrays Array( 数组 ):a set of index( 索引 ) and value( 值 ) Array:=<index, value> data structure For each index, there is a value associated with that index. representation (possible) implemented by using consecutive memory. CHAPTER 2 2
  • 3.
    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 3
  • 4.
    Arrays in C intlist[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 list[0] base address = α list[1] α + sizeof(int) list[2] α + 2*sizeof(int) list[3] α + 3*sizeof(int) list[4] α + 4*size(int) CHAPTER 2 4
  • 5.
    Arrays in C(Continued) Compare int *list1 and int list2[5] in C. Same: list1 and list2 are pointers. Difference: list2 reserves five locations. Notations: list2 - a pointer to list2[0] (list2 + i) - a pointer to list2[i] (&list2[i]) *(list2 + i) - list2[i] CHAPTER 2 5
  • 6.
    Example: 1-dimension arrayaddressing Address Contents int one[] = {0, 1, 2, 3, 4}; 1228 out address and value Goal: print 0 1230 void print1(int *ptr, int rows) 1 { 1232 2 /* print out a one-dimensional array using a pointer */ int i; 1234 3 printf(“Address Contentsn”); 1236 for (i=0; i < rows; i++) 4 printf(“%8u%5dn”, ptr+i, *(ptr+i)); printf(“n”); } *Figure 2.1: One- dimensional array addressing (p.53) call print1(&one[0], 5) CHAPTER 2 6
  • 7.
    Structures (records) struct { char name[10]; int age; float salary; } person; strcpy(person.name, “james”); person.age=10; person.salary=35000; CHAPTER 2 7
  • 8.
    Create structure datatype typedef struct human_being { char name[10]; int age; float salary; }; or typedef struct { char name[10]; int age; float salary } human_being; human_being person1, person2; CHAPTER 2 8
  • 9.
    Unions Similar to struct,but only one field is active. Example: Add fields for male and female. typedef struct { enum tag_field {female, male} sex; union { int children; int beard; } u; } sex_type; typedef struct { char name[10]; human_being person1, person2; int age; person1.sex_info.sex=male; float salary; person1.sex_info.u.beard=FALSE; date dob; sex_type sex_info; } human_being; 2 CHAPTER 9
  • 10.
    Self-Referential Structures Oneor more of its components is a pointer to itself. typedef struct { Construct a list with three nodes char data; item1.link=&item2; list *link; item2.link=&item3; } list; malloc: obtain a node list item1, item2, item3; item1.data=‘a’; a b c item2.data=‘b’; item3.data=‘c’; item1.link=item2.link=item3.link=NULL; CHAPTER 2 10
  • 11.
    Ordered List Examples linearlist: ordered list: (item1, item2, item3, …, itemn)  (MONDAY, TUEDSAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAYY, SUNDAY)  (2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace)  (1941, 1942, 1943, 1944, 1945)  (a1, a2, a3, …, an-1, an) CHAPTER 2 11
  • 12.
    Operations on OrderedList  Get the length of the list (n).  Read the items from left to right (or right to left).  Retrieve the i’th element.  Store a new value into the i’th position.  Insert a new element at the position i , causing elements numbered i, i+1, …, n to become numbered i+1, i+2, …, n+1  Delete the element at position i , causing elements numbered i+1, …, n to become numbered i, i+1, …, n- 1 array (sequential mapping)? (1)~(4) O (5)~(6) X CHAPTER 2 12
  • 13.
    Polynomials A(X)=3X20+2X5+4, B(X)=X4+10X3+3X2+1 StructurePolynomial is objects: p ( x ) = a1 x e1 + ... + an x en; a set of ordered pairs of <ei,ai> where ai in Coefficients and ei in Exponents, ei are integers >= 0 functions: for all poly, poly1, poly2  Polynomial, coef Coefficients, expon Exponents Polynomial Zero( ) ::= return the polynomial, p(x) = 0 Boolean IsZero(poly) ::= if (poly) return FALSE else return TRUE Coefficient Coef(poly, expon) ::= if (expon  poly) return its coefficient else return Zero Exponent Lead_Exp(poly) ::= return the largest exponent in poly Polynomial Attach(poly,coef, expon) ::= if (expon  poly) return error else return the polynomial poly with the term <coef, expon> inserted CHAPTER 2 13
  • 14.
    Polynomial Remove(poly, expon) ::= if (expon  poly) return the polynomial poly with the term whose exponent is expon deleted else return error Polynomial Single Mult(poly, coef, expon) ::= return the polynomial poly • coef • xexpon Polynomial Add(poly1, poly2) ::= return the polynomial poly1 +poly2 Polynomial Mult(poly1, poly2) ::= return the polynomial poly1 • poly2 End Polynomial *Structure 2.2:Abstract data type Polynomial (p.61) CHAPTER 2 14
  • 15.
    Polynomial Addition A(X)=2X8+1, B(X)=X4+10X3+3X2+1 Exp8 7 6 5 4 3 2 1 0 A(X 2 0 0 0 0 0 0 0 1 ) B(X 0 0 0 0 1 10 3 0 1 ) Coefficient CHAPTER 2 15
  • 16.
    Polynomial Addition(cont.) data structure 1: #define MAX_DEGREE 101 typedef struct { int degree; float coef[MAX_DEGREE]; /* d =a + b, where a, b, and d are polynomials */ } polynomial; d = Zero( ) while (! IsZero(a) && ! IsZero(b)) do { case 1: d = switch COMPARE (Lead_Exp(a), Lead_Exp(b)) Attach(d, Coef (a, { Lead_Exp(a)), case -1: d = Lead_Exp(a)); Attach(d, Coef (b, Lead_Exp(b)), a = Remove(a, Lead_Exp(b)); Lead_Exp(a)); b = Remove(b, Lead_Exp(b)); } break; } case 0: sum = Coef (a, Lead_Exp (a)) + Coef ( b, Lead_Exp(b)); insert any remaining terms if (sum) { of a or b into d Attach (d, sum, Lead_Exp(a)); *Program 2.4 :Initial version of padd function(p.62) a = Remove(a , Lead_Exp(a)); Advantage: easy implementation b = Remove(b , Lead_Exp(b)); } Disadvantage: waste space when CHAPTER 2 16 break; sparse
  • 17.
    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 polynomials (p.63) starta finisha startb finishb avail coef 2 1 1 10 3 1 exp 1000 0 4 3 2 0 0 1 2 3 4 5 6 specification representation poly <start, finish> A <0, 1> B CHAPTER <2, 2 5> 17
  • 18.
    storage requirements: start,finish, 2*(finish-start+1) nonparse: twice as much as (1) when all the items are nonzero MAX_TERMS 100 /* size of terms array */ typedef struct { float coef; int expon; } polynomial; polynomial terms[MAX_TERMS]; int avail = 0; *(p.62) CHAPTER 2 18
  • 19.
    Add two polynomials:D = A + B void padd (int starta, int finisha, int startb, if (coefficient) int finishb,int * startd, int *finishd) attach (coefficient, { /* add A(x) and B(x) to obtain D(x) */ terms[starta].expon); float coefficient; starta++; *startd = avail; startb++; while (starta <= finisha && startb <= break; finishb) case 1: /* a expon > b expon */ switch COMPARE(terms[starta].expon, attach(terms[starta].coef, terms[startb].expon)) terms[starta].expon); { starta++; case -1: /* a expon < b expon */ } /* add in remaining terms of A(x) */ attach(terms[startb].coef, for( ; starta <= finisha; starta++) terms[startb].expon); attach(terms[starta].coef, startb++ terms[starta].expon); break; /* add in remaining terms of B(x) */ case 0: /* equal exponents */ for( ; startb <= finishb; startb++) coefficient = terms[starta].coef+ attach(terms[startb].coef, terms[startb].coef terms[startb].expon); Analysis: O(n+m) *finishd =avail -1; where n (m) is the 2 CHAPTER number of nonzeros in A(B). } 19
  • 20.
    void attach(float coefficient,int exponent) { /* add a new term to the polynomial */ if (avail >= MAX_TERMS) { fprintf(stderr, “Too many terms in the polynomialn”); exit(1); } terms[avail].coef = coefficient; terms[avail++].expon = exponent; } *Program 2.6:Function to add anew term (p.65) Problem: Compaction is required when polynomials that are no longer needed. (data movement takes time.) CHAPTER 2 20
  • 21.
    Sparse Matrix col1 15 col2 col3 22 0 −col6 0 0 col4 col5 15 row0  0 11 3 0 0 0 row1    0 0 0 −6 0 0 row2    0 0 0 0 0 0 row3 91 0 0 0 0 0   row4  0  0 28 0 0 0  row5 5*3 6*6 (a) 15/15 (b) 8/36 *Figure 2.3:Two matrices sparse matrix data structure? CHAPTER 2 21
  • 22.
    SPARSE MATRIX ABSTRACTDATA TYPE Structure Sparse_Matrix is objects: a set of triples, <row, column, value>, where row and column are integers and form a unique combination,and value comes from the set item. functions: for all a, b ∈ Sparse_Matrix, x  item, i, j, max_col, max_row  index Sparse_Marix Create(max_row, max_col) ::= return a Sparse_matrix that can hold up to max_items = max _row  max_col and whose maximum row size is max_row and whose maximum column size is max_col. CHAPTER 2 22
  • 23.
    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 23 * Structure 2.3: Abstract data type Sparse-Matrix (p.68)
  • 24.
    (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 row col value a[0] 6 b[0] 6 c[0] 6 6 8 6 8 6 8 [1] 0 0 15 [1] 0 0 15 [1] 0 0 15 [2] 0 3 22 [2] 3 0 22 [2] 0 4 91 [3] 0 5 -15 [3] 5 0 -15 [3] 1 1 11 [4] 1 1 11 [4] 1 1 11 [4] 2 1 3 transpose transpose [5] 1 2 3 [5] 2 1 3 [5] 2 5 28 [6] 2 3 -6 [6] 3 2 -6 [6] 3 0 22 [7] 4 0 91 [7] 0 4 91 [7] 3 2 -6 [8] 5 (a) 2 28 [8] 2(b) 5 28 [8] 5 (c)0 -15 a[0].row ---- the number of rows in a a[0].col ---- the number of columns in a a[0].total ---- the total number of nonzero entries in a. CHAPTER 2 24 row, column in ascending order
  • 25.
    Sparse_matrix Create(max_row, max_col)::= #define MAX_TERMS 101 /* maximum number of terms +1*/ typedef struct { int col; # of rows (columns) int row; int value; # of nonzero terms } term; term a[MAX_TERMS] * (P.69) CHAPTER 2 25
  • 26.
    Transpose a Matrix (1)for each row i take element <i, j, value> and store it in element <j, i, value> of the transpose. difficulty: where to put <j, i, value> (0, 0, 15) ====> (0, 0, 15) (0, 3, 22) ====> (3, 0, 22) (0, 5, -15) ====> (5, 0, -15) (1, 1, 11) ====> (1, 1, 11) Move elements down very often. (2) For all elements in column j, place element <i, j, value> in element <j, i, value> CHAPTER 2 26
  • 27.
    void transpose (terma[], term b[]) /* b is set to the transpose of a */ b[currentb].row = a[j].col; { b[currentb].col = a[j].row int n, i, j, currentb; b[currentb].value = a[j].value; n = a[0].value; /* total number of elements */ currentb++ b[0].row = a[0].col; /* rows in b = columns in a */ } b[0].col = a[0].row; /*columns in b = rows in a */ } b[0].value = n; } if (n > 0) { /*non zero matrix */ currentb = 1; for (i = 0; i < a[0].col; i++) /* transpose by columns in a */ for( j = 1; j <= n; j++) /* find elements from the current column */ if (a[j].col == i) { /* element is in current column, add it to b */ * Scan the array “columns” times. Program 2.7: Transpose of a sparse matrix (p.71) ==> O(columns*elements) The array has “elements” elements.2 CHAPTER 27
  • 28.
    Discussion: compared with2-D array representation O(columns*elements) vs. O(columns*rows) elements = columns * rows when nonsparse O(columns*columns*rows) Problem: Scan the array “columns” times. Solution: 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 28
  • 29.
    Row Col Value Row Col Value a[0] 6 6 8 b[0] 6 6 8 a[1] 0 0 15 b[1] 0 0 15 a[2] 0 3 22 b[2] 0 4 91 a[3] 0 5 -15 b[3] 1 1 11 a[4] 1 1 11 b[4] 2 1 3 a[5] 1 2 3 b[5] 2 5 28 a[6] 2 3 -6 b[6] 3 0 22 a[7] 4 0 91 b[7] 3 2 -6 a[8] 5 2 28 b[8] 5 0 -15 Matrix Transposed matrix [0] [1] [2] [3] [4] [5] row_terms = 2 1 2 2 0 1 starting_pos = 1 3 4 6 8 8 CHAPTER 2 29
  • 30.
    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++) row_terms[i] = 0; for (i = 1; i <= num_terms; i++) row_term [a[i].col]++ ; starting_pos[0] = 1; for (i =1; i < num_cols; i++) starting_pos[i]=starting_pos[i-1] +row_terms [i-1]; CHAPTER 2 30
  • 31.
    for (i=1; i<= num_terms, i++) { j = starting_pos[a[i].col]++; 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 Compared with 2-D array representation O(columns+elements) vs. O(columns*rows) elements --> columns * rows O(columns+elements) --> O(columns*rows) Cost: Additional row_terms and starting_pos arrays are required. Let the two arrays row_terms and starting_pos be shared. CHAPTER 2 31
  • 32.
    Sparse Matrix Multiplication Definition:[D]m*p=[A]m*n* [B]n*p Procedure: Fix a row of A and find all elements in column j of B for j=0, 1, …, p-1. Alternative 1. Scan all of B to find all elements in j. Alternative 2. Compute the transpose of B. (Put all column elements consecutively) 1 0 0 1 1 1 1 1 1 1 0 0 0 0 0 = 1 1 1      1 0 0 0 0 0 1 1 1      CHAPTER 2 32 *Figure 2.5:Multiplication of two sparse matrices (p.73)
  • 33.
    The String AbstractData Type  String  DEFINITION String can be denoted as: S= s0,……, sn-1, where si are characters taken from the character set of the programming language.  if n = 0, then S is an empty or null string. CHAPTER 2 33
  • 34.
    REPRESENTATION #define MAX_SIZE 100/* maximum size of string */ char s [MAX_SIZE ] = { " dog "}; char s [ ] = { " dog "}; char t [MAX_SIZE ] = {"house "}; char t [ ] = {"house "}; s[0] s[1] s[2] s[3] d o g n t[0] t[1] t[2] t[3] t[4] t[5] h o u s e n CHAPTER 2 34
  • 35.
    structure String is objects:a finite set of zero or more characters. Functions: for all s, t String, i, j, m non-negative integers  String Null(m) ::= return a string whose maximum length is m characters, but is initially set to NULL we write NULL as ""  Integer Compare(s,t ) ::= if s equals t return 0 else if s precedes t return -1 else return 1  Boolean IsNull( s ) ::= if ( compare( s, NULL)) return FALSE else return TRUE  INTEGER Length (s) ::= if (COMPARE (s, NULL)) return the number of characters in s else return 0  String Concat (s, t ) ::= if ( COMPARE (t, NULL)) return a string whose elements are those of s followed by those of t else return s.  String Substr (s, i, j ) ::= if ((j > 0 )&& (i + j -1 ) < length(s)) return the string containing the characters of s at the position i, i+1, … , i + j -1. else return NULL  end String CHAPTER 2 35
  • 36.
    〖 example 〗string insertion  OPERATIONS ( list ) Insert string t into string s at position i #include <string.h> #define MAX_SIZE 100 /* maximum size of string */ char string1 [MAX_SIZE ] , *s = string1; char string2 [MAX_SIZE ] , *t = string2; CHAPTER 2 36
  • 37.
    〖 example 〗string insertion void strnins (char *s, char *t, int i) { / * insert string t into string s at position i */ char string[MAX_SIZE], *temp = string; if ( i < 0 && i > strlen ( s ) ) { fprintf ( stderr, " position is out bounds n "); exit (1); } if (!strlen (s )) strcpy ( s, t); else if (strlen ( t )) { strncpy ( temp, s, i); strcat ( temp, t) ; strcat ( temp, (s + i )); strcpy ( s, temp ); } } CHAPTER 2 37
  • 38.
    〖 example 〗string insertion s a m o b i l e 0 t u t o 0 temp 0 initially temp a 0 (a) after strncpy ( temp, s ,i) temp a u t o 0 (b) after strcat ( temp, t) temp a u t o m o b i l e 0 (c) after strcat ( temp, ( s + i )) CHAPTER 2 38
  • 39.
    patter a a b 〖 example 〗 patterm matching j lastp no match a b a b b a a b a a start endmatch lasts no match a b a b b a a b a a start endmatch lasts no match a b a b b a a b a a start endmatch lasts no match a b a b b a a b a a start endmatch lasts no match a b a b b a a b a a start endmatch lasts match a b a b b a a b a a CHAPTER 2 start endmatch lasts 39
  • 40.
    Example: Pattern Matching intnfind ( char *string, char *pat ) { /* match the last character of patter first, and then match from the beginning */ int i, j, start = 0; int lasts = strlen (string ) -1; int lastp = strlen ( pat) -1 ; int endmatch = lastp; for ( i = 0; endmatch < = lasts; endmatch++, start++) { if ( string [endmatch ] == pat [lastp ]) for ( j = 0; i = start; j < lastp && string [ i ] ==pat [ j ]; i++, j++) ; if ( j == lastp ) return start; /*successful */ } return -1; } n ----- the length of pat m ----- the length of string the worst case : O(n *m) CHAPTER 2 40
  • 41.
    String Pattern Matching:The Knuth- Morris-Pratt Algorithm  Definition: If p= p0p1. . .pn-1 is a pattern, then its failure function, f, is defined as:  f(j)= largest k< j such that p0p1. . .pk= pj-kpj-k+1. . .pj, if such a k>= 0 exists  = -1, otherwise CHAPTER 2 41
  • 42.
     Example J 0 1 2 3 4 5 6 7 8 9 pat a b c a b c a c a b f -1 -1 -1 0 1 2 3 -1 0 1  Example J 0 1 2 3 4 5 6 7 pat a a b a a a a b f -1 0 -1 0 1 1 1 2 CHAPTER 2 42
  • 43.
    #include <stdio.h> #include <string.h> #definemax_sring_size 100 #define max_pattern_size 100 int pmatch ( ); void fail ( ); int failure [ max_pattern_size ]; char pat [ max_pattern_size ]; char string [ max_string_size ]; CHAPTER 2 43
  • 44.
    int pmatch (char *string, char *pat) { /* Knuth, Morris, Pratt string matching algorithm, O(strlen(string)) */ int i = 0, j = 0; int lens = strlen ( string ); int lenp = strlen ( pat); Lens=11,lenp = 6 while ( i < lens && j < lenp ) { if (string [ i ] == pat [ j ] ) { i=5,j=5-j=failue[4]+1=4 i ++; j ++} else if ( j == 0 ) i ++; else j = failure [ j - 1 ] + 1; } return (( j == lenp ) ? ( i - lenp ) : -1 ); } j i Example J 0 1 2 3 4 5 string =“a a a a a a a a a a ab” pat a a a a a b f -1 0 1 2 3 0 CHAPTER 2 44
  • 45.
    computting the failurefunction O(strlen(pat)) void fail ( (char *pat ) ( /* compute the pattern's failure function */ int n = strlen (pat ); failure [ 0 ] = -1; for ( j = 1; j < n; j ++) { i = failure [ j -1 ]; while ( ( pat [ j ] != pat [ i +1 ] && ( i >= 0)) i = failure [ i ]; if ( pat [ j ] == pat [ i + 1] ) failure [ j ] == i + 1; else failure [ j ] = -1; } }  Example J 0 1 2 3 4 5 6 7 Example pat a a b a a a a b J 0 1 2 3 4 5 6 7 8 9 f -1 0 -1 0 1 1 1 2 pat a b c a b c a c a b f -1 -1 -1CHAPTER 20 1 0 1 2 3 -1 45

Editor's Notes

  • #8 Here is structure data type. Compared with array, the elements’ types in structures can be different.
  • #19 Since the second method considers exponent information in the array, so the size of the array doubles.
  • #20 It is worth mentioning that the elements of A and B are both stored in array terms.
  • #25 As we can see that, if we sort the elements in matrix by row, the corresponding elements of the transposed matrix is unordered. So we should adopt column as the sort element.
  • #30 Row_terms means the number of non-zero elements in the i-th row in the transposed matrix.