以列為主

Download Report

Transcript 以列為主

Data Structure in C
─ 陣列與結構
大綱





陣列
結構和聯結
多項式抽象資料型態
稀疏矩陣抽象資料型態
上三角和下三角表示法
1
陣列

陣列是一組序對,<index,value>,其中每一
個索引(index)定義了一個相關連的值(value)


陣列的宣告 int list[5], *plist[5];
記憶體配置 變數
記憶位址
(一維陣列) list[0]
base address = α
list[1]
α + size[int]
list[2]
α + 2 * size[int]
list[3]
α + 3 * size[int]
list[4]
α + 4 * size[int]
2

陣列的抽象資料型態(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 
Array Create(j, list)
Item Retrieve(A, i)
::=
::=
integer
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.
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
二維陣列

若有一二維陣列是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
4
三維陣列

若有一三維陣列是A[0:u1-1, 0:u2-1, 0:u3-1]。
一般三維陣列皆先化為二維陣列後,再對應
到一維陣列,對應方式也有兩種:(1)以列為
主,(2)以行為主
u1
u2
u3
5
三維陣列 (續)

以列為主:視此陣列有u1個u2 * u3的二維陣列,
每一個二維陣列有u2個元素,每個u2皆有u3d個
空間A(i, j,k) = l0+i*u2u3d+j*u3d+k*d
i*u2u3
u3
u3
...
u2
A(0, u2, u3)
l0
...
u2
A(1, u2, u3)
A(i, u2, u3)
A(u1-1, u2, u3)
l0
6
三維陣列 (續)

以行為主:視此陣列有u3個u1 * u2的二維陣列,
每一個二維陣列有u2個元素,每個u2皆有u1d個
空間A(i, j,k) = l0+k*u1u2d+j*u1d+i*d
k*u1u2
u1
u1
...
u2
A(u1, u2,0)
l0
...
u2
A(u1, u2,1)
A(u1, u2,k)
A(u1, u2, u3-1)
l0
7
n維陣列

若有一n維陣列是A[0:u1-1, 0:u2-1, 0:u3-1, … ,
0:un-1]。同樣地,n維陣列亦有兩種表式方
法:(1)以列為主,(2)以行為主

參考課本pp.2-9~2-10
8
結構和聯結

結構是將不相同型態的資料群集在一起


Ex. struct {
char name[10];
int age;
float salary;
} person;
聯結的宣告與結構類似,但union中的欄位必須
共用記憶空間

Ex. Union {
int children;
int bread;
} u;
9
結構和聯結

自我參考結構(self-referential structure)是
一種結構,其中的一個或多個組成元素
是指向自身的指標


通常需要動態記憶管理程式(malloc和free)來
明確地取得或釋回記憶體
Ex. Type struct list {
char data;
list *link;
};
10
多項式抽象資料型態

何謂多項式?



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))
11

多項式的ADT
structure Polynomial is
objects: p(x) = a1xe1 + … + anxen; a set of ordered pairs of <ei, ai> where ai in
Coefficients and ei in Exponents, ei are integers >=0
functions:
 Exponents
For all poly, poly1, poly2 Polynomial, coef Coefficients, expon
Polynomial Zero()
::=
return the polynomial p(x)=0
Boolean IsZero(poly)
::=
if(poly) return FALSE else return TRUE
if(expon poly) return its coefficient else
Coefficient Coef(poly,expon) ::=
return zero
Exponent Lead_Exp(poly)
::=
return the largest exponent in poly
 poly) return error else
Polynomial Attach(poly, coef, expon) ::= if(expon
Polynomial Remove(poly, expon)
::=
return the polynomial poly with
the term<coef, expon> inserted
 poly) return the
if(expon
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)
Polynomial Mult(poly1, poly2)
end Polynomial
::=
::=
return the polynomial poly1+poly2
return the polynomial poly1 × poly2
多項式抽象資料型態 (續)

在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)= n
可表示為:
i
a
x

i
a.degree=n
i 0
a.coef[i]=an-i, 0 i n
 
13
多項式抽象資料型態 (續)

若多項式是稀疏的,係數不為0的項次個數
相對於係數為0的項次個數是很小時,會有
記憶體浪費的現象
#define MAX_TERMS 100 /*size of terms array*/
typedef struct{
float coef;
int expon;
} polynomial;
Polynomial terms[MAX_TERMS];
int avail=0;
14
多項式抽象資料型態 (續)

Ex. 將A(X)=2x1000+1和B(X)=x4+10x3+3x2+1相加
starta
finisha
startb
coef
2
1
1
10
3
1
exp
1000
0
4
3
2
0
0
1
2
3
4
5
finishb
avail
6
15
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++;
}
稀疏矩陣抽象資料型態



在數學上,一個矩陣包含m列和n行的元素。
一般寫為m × n,表示矩陣有m列n行,共有
mn個元素。若m = n,矩陣為一方陣
在計算機科學上,一個矩陣的標準表示法為
二維陣列,定義為a[MAX_ROWS][MAX_COLS]
若矩陣中包含了許多的0,我們稱為“稀疏矩
陣”。而多少0少能算是稀疏?並沒有明絶對
的定對。一般而言,大於1/2個就可稱之
19
稀疏矩陣抽象資料型態 (續)

稀疏矩陣表示法
#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的元素。
20
稀疏矩陣抽象資料型態 (續)
col0 col1 col2 col3 col4 col5
row
col
value
a[0]
6
6
8
row0
15
0
0
22
0
-15
a[1]
0
0
15
row1
0
11
3
0
0
0
a[2]
0
3
22
row2
0
0
0
-6
0
0
a[3]
0
5
-15
row3
0
0
0
0
0
0
a[4]
1
1
11
row4
91
0
0
0
0
0
a[5]
1
2
3
row5
0
0
28
0
0
0
a[6]
2
3
-6
a[7]
4
0
91
a[8]
5
2
28
21
structure Sparse_Matrix is
稀疏矩陣
的ADT
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:
 index
for all a,b Sparse_Matrix, x item, I, j, max_col, max_row
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
稀疏矩陣抽象資料型態 (續)

轉置矩陣是將矩陣的行與列互換。也就是將
矩陣中的每個元素a[i][j]變成轉置矩陣中的
元素b[j][i]
row
col
value
row
col
value
a[0]
6
6
8
a[0]
6
6
8
a[1]
0
0
15
a[1]
0
0
15
a[2]
0
3
22
a[2]
0
4
91
a[3]
0
5
-15
a[3]
1
1
11
a[4]
1
1
11
a[4]
2
1
3
a[5]
1
2
3
a[5]
2
5
28
a[6]
2
3
-6
a[6]
3
0
22
a[7]
4
0
91
a[7]
3
2
-6
a[8]
5
2
28
a[8]
5
0
-15
23
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++; }
}
}
上三角和下三角表示法


若一矩陣的對角線以下的元素均為零時,亦
即aij=0,i>j,則稱此矩陣為上三角形矩陣
(upper triangular matrix)
若一矩陣的對角線以上的元素均為零時,亦
即aij=0,i<j,則稱此矩陣為上三角形矩陣
(lower triangular matrix)
a11
a12
a13
a14
a11
0
0
0
0
a22
a23
a24
a21
a22
0
0
0
0
a33
a34
a31
a32
a33
0
0
0
0
a44
a41
a42
a43
a44
25
上三角和下三角表示法 (續)

一個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
a11
a12
a13
a14
...
a22
a23
D(1) D(2) D(3) D(4) ... D(n+1) D(n+2)

a24
D(n+3)
...
aij
...
ann
...
D(k)
...
D([n(n+1)]/2)
以列為主(下三角形矩陣):一個n*n的下三角形矩陣
對映至D陣列時,當aij=D(k),則k = [i(i-1)]/2+j
a11
a21
a22
a31
a32
...
aij
...
ann
D(1) D(2) D(3) D(4) D(5) ... D(k) ... D([n(n+1)]/2)
26
上三角和下三角表示法 (續)

以行為主(上三角形矩陣):一個n*n的上三角形矩陣
對映至D陣列時,當aij=D(k),則k = [j(j-1)]/2+I
a11
a12
a22
a13
...
D(1) D(2) D(3) D(4) ...

aij
...
ann
D(k) ... D([n(n+1)]/2)
以行為主(下三角形矩陣):一個n*n的下三角形矩陣
對映至D陣列時,當aij=D(k),則k = n(j-1)-[j(j-1)]/2+ji
a11
a21
a31
a41
...
aij
...
ann
D(1) D(2) D(3) D(4) ... D(k) ... D([n(n+1)]/2)
27