Post on 19-Dec-2015
Data Structure in C ─ 陣列與結構
2
大綱 陣列 結構和聯結 多項式抽象資料型態 稀疏矩陣抽象資料型態 上三角和下三角表示法
3
陣列 陣列是一組序對, <index,value> ,其中每一個索引 (index) 定義了一個相關連的值(value) 陣列的宣告 int list[5], *plist[5]; 記憶體配置 ( 一維陣列 )
變數 記憶位址
list[0] base address = α
list[1]
list[2]
list[3]
list[4]
α + size[int]
α + 2 * size[int]
α + 3 * size[int]
α + 4 * size[int]
陣列的抽象資料型態 (ADT:abstract data type)( 是一種資料型態,它的組織方式使得物件的規格與物件上的運算之規格和該物件的內部表示法與運算的實作法是獨立的 )
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(iindex) 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
5
二維陣列 若有一二維陣列是 A[0:u1-1, 0:u2-1] ,表示此陣列有 u1列及 u2行,也就是每一列是由 u2個元素組成。二維陣列化成一維陣列時,對應方式有兩種: (1)以列為主, (2)以行為主 以列為主:視此陣列有 u1個元素 (0, 1, 2,…,u1-1) ,每一元素有 u2個單位,每個單位佔 d 個空間 A(i,
j) = l0+i*u2d+j*d
以行為主:視此陣列有 u2個元素 (0, 1, 2,…,u2-1) ,每一元素有 u1個單位,每個單位佔 d 個空間 A(i, j) = l0+j*u1d+i*d
6
三維陣列 若有一三維陣列是 A[0:u1-1, 0:u2-1, 0:u3-1] 。一般三維陣列皆先化為二維陣列後,再對應到一維陣列,對應方式也有兩種: (1)以列為主, (2)以行為主
u1
u2
u3
7
三維陣列 ( 續 ) 以列為主:視此陣列有 u1 個 u2 * u3的二維陣列,每一個二維陣列有 u2個元素,每個 u2皆有 u3d
個空間 A(i, j,k) = l0+i*u2u3d+j*u3d+k*d
...
A(0, u2, u3) A(1, u2, u3)
l0
u3
i*u2u3
u2
A(u1-1, u2, u3)
l0
u3
u2
A(i, u2, u3)
...
8
三維陣列 ( 續 ) 以行為主:視此陣列有 u3 個 u1 * u2的二維陣列,每一個二維陣列有 u2個元素,每個 u2皆有 u1d
個空間 A(i, j,k) = l0+k*u1u2d+j*u1d+i*d
...
A(u1, u2,0)
l0
u1
k*u1u2
u2
A(u1, u2, u3-1)
l0
u1
u2 ...
A(u1, u2,1) A(u1, u2,k)
9
n 維陣列 若有一 n 維陣列是 A[0:u1-1, 0:u2-1, 0:u3-1, …
, 0:un-1] 。同樣地, n 維陣列亦有兩種表式方法: (1)以列為主, (2)以行為主 參考課本 pp.2-9~2-10
10
結構和聯結 結構是將不相同型態的資料群集在一起
Ex. struct {
char name[10];
int age;
float salary;
} person;
聯結的宣告與結構類似,但 union 中的欄位必須共用記憶空間
Ex. Union {
int children;
int bread;
} u;
11
結構和聯結 自我參考結構 (self-referential structure) 是一種結構,其中的一個或多個組成元素是指向自身的指標 通常需要動態記憶管理程式 (malloc 和 free)來明確地取得或釋回記憶體
Ex. Type struct list {
char data;
list *link;
};
12
多項式抽象資料型態 何謂多項式?
Ex. A(x)=3x20+2x5+4 與 B(x)=x4+10x3+3x2+1 axe,其中 x是變數, a 是係數,而 e 是指數多項式最大的指數指稱為次方(degree) ,等於 0 的係數不必寫出,指數為0 的項目不必寫出數
多項式加法 A(x) + B(x) = (ai+bi)xi
多項式乘法 A(x) * B(x) = (aixi * (bjxj))
多項式的 ADTstructure Polynomial is
objects: p(x) = a1xe1 + … + anx
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, poly2Polynomial, coefCoefficients, exponExponents
Polynomial Zero() ::= return the polynomial p(x)=0
Boolean IsZero(poly) ::= if(poly) return FALSE else return TRUE
Coefficient Coef(poly,expon) ::= if(exponpoly) return its coefficient else
return zero
Exponent Lead_Exp(poly) ::= return the largest exponent in poly
Polynomial Attach(poly, coef, expon) ::= if(exponpoly) return error else
return the polynomial poly with
the term<coef, expon> inserted
Polynomial Remove(poly, expon) ::= if(exponpoly) return the
polynomial poly with the term whose
exponent is expon deleted else return
error
Polynomial SingleMult(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
14
在 C 中表示多項示的方法是使用 typedef 建立 polynomial 型態#define MAX_DEGREE 101 /*Max degree of polynomial+1*/typedef struct{ int degree; float coef[MAX_DEGREE]; } polynomial;
若 a 的型態是 polynomial ,且n<MAX_DEGREE ,
則多項式 A(x)= 可表示為: a.degree=n a.coef[i]=an-i, 0 i n
多項式抽象資料型態 ( 續 )
n
i
ii xa
0
15
多項式抽象資料型態 ( 續 ) 若多項式是稀疏的,係數不為 0 的項次個數相對於係數為 0 的項次個數是很小時,會有記憶體浪費的現象
#define MAX_TERMS 100 /*size of terms array*/typedef struct{
float coef;
int expon;
} polynomial;
Polynomial terms[MAX_TERMS];
int avail=0;
16
多項式抽象資料型態 ( 續 ) Ex. 將 A(X)=2x1000+1 和 B(X)=x4+10x3+3x2+1 相加
2 1 1 10 3 1
1000 0 4 3 2 0
coef
exp
0 1 2 3 4 5 6
starta startb availfinishbfinisha
void padd (int starta, int finisha, int startb, int finishb, int *stard, 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;
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++;
break;
}
/* 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;
}
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].conf = coefficient;
terms[avail].expon = exponent;
avail++;
}
20
稀疏矩陣抽象資料型態 在數學上,一個矩陣包含 m 列和 n 行的元素。一般寫為 m × n ,表示矩陣有 m 列 n 行,共有 mn 個元素。若 m = n ,矩陣為一方陣
在計算機科學上,一個矩陣的標準表示法為二維陣列,定義為 a[MAX_ROWS][MAX_COLS]
若矩陣中包含了許多的 0 ,我們稱為“稀疏矩陣”。而多少 0 少能算是稀疏?並沒有明絶對的定對。一般而言,大於 1/2 個就可稱之
21
稀疏矩陣抽象資料型態 ( 續 ) 稀疏矩陣表示法 #define MAX_TERMS 101 /*maximum number of terms +1*/
typedef struct{ int col; int row; int value; } term;term a[MAX_TERMS]; 若將稀疏矩陣以陣列 a 表示, a[0].row 為列數,
a[0].col 為行數,而 a[0].value 為全部不為 0 之元素個數。另外, a[1]~a[8] 是儲存代表不為 0 的元素。
22
稀疏矩陣抽象資料型態 ( 續 )
15
0
91
11 3
28
22
-6
-15row0
col0
row1
row2
row3
row4
row5
col1 col2 col3 col4 col5
0
0
0
0 0 0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
a[0]
row col value
a[1]
a[2]
a[3]
a[4]
a[5]
a[6]
a[7]
a[8]
6 6 8
0
0
0
1
1
2
4
5
0
3
5
1
2
3
0
2
15
22
-15
11
3
-6
91
28
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_Matrix 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.
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.
end Sparse_Matrix
稀疏矩陣的 ADT
24
稀疏矩陣抽象資料型態 ( 續 ) 轉置矩陣是將矩陣的行與列互換。也就是將矩陣中的每個元素 a[i][j] 變成轉置矩陣中的元素 b[j][i]
a[0]
row col value
a[1]
a[2]
a[3]
a[4]
a[5]
a[6]
a[7]
a[8]
6 6 8
0
0
0
1
1
2
4
5
0
3
5
1
2
3
0
2
15
22
-15
11
3
-6
91
28
a[0]
row col value
a[1]
a[2]
a[3]
a[4]
a[5]
a[6]
a[7]
a[8]
6 6 8
0
0
1
2
2
3
3
5
0
4
1
1
5
0
2
0
15
91
11
3
28
22
-6
-15
void transpose(term a[], term b[])/* b is set to the transpose of a */{ int n, i, j, currentb; n = a[0].value; /* total number of elements */ 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 the 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*/ b[currentb].row = a[j].col; b[currentb].col = a[j].row; b[currentb].value = a[j].value; currentb++; } }}
26
上三角和下三角表示法 若一矩陣的對角線以下的元素均為零時,亦
即 aij=0 , i>j ,則稱此矩陣為上三角形矩陣(upper triangular matrix)
若一矩陣的對角線以上的元素均為零時,亦即 aij=0 , i<j ,則稱此矩陣為上三角形矩陣(lower triangular matrix)
a11
0
0
0
0
0 0
a34
a24
a14
a33
a23
a13
a22
a12
a44
a11 0 0 0
0 0
0
a43
a21
a42
a33a32a31
a22
a41 a44
27
上三角和下三角表示法 ( 續 ) 一個 n*n 個的上下三角形矩陣共有 [n(n+1)]/2 個元素,依序對映至 D(1: [n(n+1)]/2)
以列為主 ( 上三角形矩陣 ) :一個 n*n 的上三角形矩陣對映至 D 陣列時,當 aij=D(k) ,則 k = n(i-1)-[i(i-1)]/2+j
以列為主 ( 下三角形矩陣 ) :一個 n*n 的下三角形矩陣對映至 D 陣列時,當 aij=D(k) ,則 k = [i(i-1)]/2+j
a11 a14a13a12 ... a24a23a22 aij ann... ...
D(1) D(4)D(3)D(2) ... D(n+3)D(n+2)D(n+1) D(k) D([n(n+1)]/2)... ...
a11 a31a22a21 ...a32 aij ann...
D(1) D(4)D(3)D(2) D([n(n+1)]/2)D(5) D(k)... ...
28
上三角和下三角表示法 ( 續 ) 以行為主 ( 上三角形矩陣 ) :一個 n*n 的上三角形矩陣對映至 D 陣列時,當 aij=D(k) ,則 k = [j(j-1)]/2+I
以行為主 ( 下三角形矩陣 ) :一個 n*n 的下三角形矩陣對映至 D 陣列時,當 aij=D(k) ,則 k = n(j-1)-[j(j-1)]/2+ji
a11 a13a22a12 ... aij ann...
D(1) D(4)D(3)D(2) ... D(k) D([n(n+1)]/2)...
a11 a41a31a21 ... aij ann...
D(1) D(4)D(3)D(2) D([n(n+1)]/2)D(k)... ...