CS 235102 Data Structures (資料結構) Chapter 2: Arrays and Structures Spring 2012 Arrays One Dimensional Array: int A[10]; Two dimensional Array: int A[10][25]; 1 Polynomial – Abstract Data Type (ADT) Object: Polynomial. Operations: Boolean IsZero(poly) ::= return FALSE or TRUE. Coefficient Coeff(poly, expon) ::= return coefficient of xexpon Polynomial Add(poly1, poly2) ::= return poly1 + poly2 Polynomial Subtract(poly1, poly2) ::= return poly1 - poly2 2 First Representation as Arrays Unique exponent arranged in decreasing order: Coefficient …… MaxDeg MaxDeg-1 0 degrees degree (the degree of the polynomial) Eg. P(x)=x5+4x3+2x2+1 degree = 5 0 … 1 0 4 2 0 1 3 First Representation as Arrays In C language: #define MAXDEGREE 101 typedef struct { int degree; int coef[MAXDEGREE] } polynomial; Operations: addition, subtraction … Easy to carry out Just adding/subtracting the corresponding terms, respectively. (See next slide …) 4 First Representation as Arrays Eg. Addition of two polynomials: polynomial addp(polynomial a, polynomial b) { polynomial c; c.degree = max(a.degree, b.degree) for (i=0; i<=MAXDEGREE; i++) c.coef[i] = a.coef[i] + b.coef[i]; return c; } Disadvantage: Sparse polynomial ==> waste of space !! 5 2nd Representation As Arrays Only represent non-zero terms Need to represent non-zero exponents and its corresponding coefficients Eg. A(x) = 2x1000 + 1 B(x) = x4 + 10x3 + 3x2 + 1 startA startB finishA finishB avail Coef 2 1 1 10 3 1 … Exp 1000 0 4 3 2 0 … 6 2nd Representation As Arrays In C: typedef struct { int coeff, exp; } polynomial; polynomial terms[MAX_TERMS]; int avail = 0; Comparisons of two representations: If polynomial sparse, 2nd repre. is better. If polynomial full, 2nd repre. is double size of 1st. 7 Addition of Polynomials (padd) Operation: C(x) = A(x) + B(x) Eg. A(x) = x5 + 9x4 + 7x3 + 2x B(x) = x6 + 3x5 + 6x + 3 padd() { p point to head of A q point to head of B while ( !IsZero(p) && !IsZero(q) ) { switch (compare(Exps of p and q) ) { “>”: attach p to C; advance p to next element in A; break; “<”: attach q to C; advance q to next element in B; break; “=”: add coefs of p and q; attach it to C; advance p to next element in A; advance q to next element in B; } } Attach remaining terms of A or B into C; } 8 Addition of Polynomials (padd) An running example for padd(): C(x) = A(x) + B(x) A(x) = x5 + 9x4 + 7x3 + 2x p p p B(x) = x6 + 3x5 + 6x + 3 q q q p p q C(x) = x6 + (1+3)x5 + 9x4 + 7x3 + (2+6)x + 3 = x6 + 4x5 + 9x4 + 7x3 + 8x + 3 9 Time Complexity of padd Inside the while loop: O(1) time How many times the “while loop” is executed in the worst case ? Let A(x) have m terms, and B(x) have n terms. In each iteration, we access next element in A(x) or B(x), or both. Worst case: m + n – 1 eg. It happens when A(x) = 7x5 + x3 + x; B(x) = x6 + 2x4 + 6x2 +3 Remaining terms in A(x): O(m) Remaining terms in B(x): O(n) Hence, total running time = O(m + n) 10 Matrix Object: Matrix. – Abstract Data Type (ADT) dimension = #rows x #cols col. 1 col. 0 col. 2 -27 3 6 82 A = 109 -64 Operations: 12 8 48 27 Matrix Transpose(matrixA) ::= return transpose of matrixA 4 -2 11 9 47 row 0 row 1 row 2 row 3 row 4 Matrix Add(matrixA, matrixB) ::= return (matrixA + matrix B) Matrix Multiply(matrixA, matrixB) ::= return (matrixA * matrixB) 11 Matrix Representation We use arrays to represent matrices. Use array a[M][N] to store a matrix A(M, N). Use a[i][j] to store A(i, j). 12 Operations: Transpose & Add c transpose(a) // a: m x n matrix for (i=0; i<rowA; i++) for (j=0; j<colA; j++) c[j][i]=a[i][j]; // O(m) // O(n) Running time = O(mn) c add(a, b) // a, b: m x n matrices for (i=0; i<rowA; i++) // O(m) for (j=0; j<colA; j++) // O(n) c[i][j]=a[i][j]+b[i][j]; Running time = O(mn) 13 Operations: Multiply c multiply(a, b) //a: m x n mat., b: n x p mat. x c: m x p mat. = for (i=0; i<rowA; i++) { // O(m) for (j=0; j<colB; j++) { // O(p) sum=0; for (k=0; k<colA; k++) // O(n) sum += a[i][k]*b[k][j]; c[i][j]=sum; } } Running time = O(mnp) 14 Sparse Matrices An example sparse matrix: A= 15 0 0 0 91 0 0 11 0 0 0 0 0 22 3 0 0 -6 0 0 0 0 28 0 0 -15 0 0 0 0 0 0 0 0 0 0 A lot of “zero” entries. Thus large memory space is wasted. Could we use other representation to save memory space ?? 15 Representation for Sparse Matrices Use triple <row, col, value> to characterize an element in the matrix. Use array of triples a[] to represent a matrix. row by row within a row, column by column row a[0] a[1 ] a[2] a[3] a[4] a[5] a[6] a[7] a[8] 6 0 0 0 1 1 2 4 5 col value 6 0 3 5 1 2 3 0 2 8 15 22 -15 11 3 -6 91 28 16 Representation for Sparse Matrices In C: typedef struct { int col, row, value; } term; term a[MAX_TERMS]; 17 Operations: Transpose c transpose(a) // a: m x n matrix //Algorithm 1: for each row i { take element (i, j, value) and store it as (j, i, value). } row col value row col value Eg. a[0] a[1 ] a[2] a[3] a[4] a[5] a[6] a[7] a[8] 6 0 0 0 1 1 2 4 5 6 0 3 5 1 2 3 0 2 8 15 22 -15 11 3 -6 91 28 c[0] c[1 ] c[2] c[3] c[4] c[5] c[6] c[7] c[8] 6 0 3 5 1 2 3 0 2 6 0 0 0 1 1 2 4 5 8 15 22 -15 11 3 -6 91 28 18 Operations: Transpose Problem: If we just place them consecutively, we need to do a lot of insertions to make the ordering right. row col value c[0] c[1 ] c[2] c[3] c[4] c[5] c[6] c[7] c[8] 6 0 3 5 1 2 3 0 2 6 0 0 0 1 1 2 4 5 8 15 22 -15 11 3 -6 91 28 19 Alg. 2 for Transpose Algorithm 2: a[0] a[1 ] a[2] a[3] a[4] a[5] a[6] a[7] a[8] row col value 6 0 0 0 1 1 2 4 5 6 0 3 5 1 2 3 0 2 8 15 22 -15 11 3 -6 91 28 row col value c[0] c[1 ] c[2] c[3] c[4] c[5] c[6] c[7] c[8] 6 0 0 1 2 2 3 3 5 6 0 4 1 1 5 0 2 0 8 15 91 11 3 28 22 -6 -15 Find all elements in col. 0, and store them in row 0; Find all elements in col. 1, and store them in row 1; … … … … etc 20 Alg. 2 for Transpose Algorithm 2 in C: for (j=0; j<#col; j++) { //O(#col) for all elements in col j { //O(#terms) place element (i, j, value) in the next position of array c[]; } } Running time = O(#col x #terms) 21 Alg. 3: Fast Transpose Algorithm 3: c transpose(a) Find number of terms in a row in c[], and then calculate the starting position of each row in c[]. Put the terms in a[] into correct position in c[] Scan through all terms in a[] only twice. row col value a[0] a[1 ] a[2] a[3] a[4] a[5] a[6] a[7] a[8] 6 0 0 0 1 1 2 4 5 6 0 3 5 1 2 3 0 2 8 15 22 -15 11 3 -6 91 28 [0] [1] [2] [3] [4] [5] rowTerms 2 1 2 2 0 1 rowStart 1 3 4 6 8 8 22 Alg. 3: Fast Transpose Algorithm 3: c transpose(a) Positions of rowStart[i] row col value c[0] c[1 ] c[2] c[3] c[4] c[5] c[6] c[7] c[8] 6 0 6 0 8 15 rowStart[0] = 1 rowStart[1] = 3 rowStart[2] = 4 rowStart[3] = 6 rowStart[4] = rowStart[5] = 8 rowStart[i] increment by 1 after it is occupied. 23 Alg. 3: Fast Transpose Algorithm 3 in C: FastTranspose(term a[], term c[]) { initialize c[0]; initialize rowTerms[] to 0; for ( i=1; i<=#terms; i++ ) rowTerms[a[i].col] += 1; Compute rowStart[] from rowTerms[]; for ( i=1; i<=#terms; i++ ) { assign data in a[i] to c[rowStart[a[i].col]]; rowStart[a[i].col] += 1; } } 24 Alg. 3: Fast Transpose Algorithm 3 in C: FastTranspose(term a[], term c[]) { initialize c[0]; initialize rowTerms[] to 0; // O(#col) for ( i=1; i<=#terms; i++ ) rowTerms[a[i].col] += 1; // O(#terms) Compute rowStart[] from rowTerms[]; // O(#col) for ( i=1; i<=#terms; i++ ) { // O(#terms) assign data in a[i] to c[rowStart[a[i].col]]; rowStart[a[i].col] += 1; } } Running time = O(#col + #terms) 25 Running Times: Alg. 3 vs 2D-Array-Alg. Alg. 3: 2D-array-alg.: O(#col + #terms) O(#col x #rows) When #terms = #col x #rows (dense matrix), Alg. 3 has same time complexity as 2D-array-alg. When #terms is small (sparse matrix), Alg. 3 is faster than 2D array representation. 26 Fast Multiply for Sparse Matrices c multiply(a, b) //a: m x n mat., b: n x p mat. x c: m x p mat. = FastMultiply(term a[], term b[], term c[]) { FastTranspose(b, newB); for each row i of a[] { for each row j of newB[] { multiply row i & row j using similar proc. as padd(); //see next slide for Eg. } } } “Good for sparse” Running time = O(rows(a) x terms(b) + cols(b) x terms(a) ) For details, please refer to textbook !! 27 An Example for Fast Multiply c FastMultiply(a, b) c: m x p mat. a: m x n mat. x 0 5 2 0 0 7 = b: n x p mat. 3 0 4 3 6 5 28 An Example for Fast Multiply c FastMultiply(a, b) c: m x p mat. x = a: m x n mat. newB: p x n mat. 0 5 2 0 0 7 3 0 4 3 6 5 p p p q q q q q x = (2)(4) + (7)(5) = 43 29 Time Complexity of Fast Multiply a: m x n mat. newB: pxn mat. c: m x p mat. q for computing one row of c = terms(b) for computing all rows of c = rows(a) x terms(b) Similarly, # of jumps of p = cols(b) x terms(a) c: m x p mat. = # of jumps of q : newB = newB p _Total time=O(rows(a) x terms(b) + cols(b) x terms(a) ) 30