第二章 数组与结构
2.1 ADT数组
首先把数组作为抽象数据型(ADT)进行讨论。直观上,数组是由下标(或称为索引)和值所组成的序对<index,value>集合,其中对于每个有定义的下标,都存在一个与其关联的值。这在数学上称为对应或映射。
一维数组
int list[5]; 定义了五个整数。
int *plist[5]; 定义了五个指向整型的指针。
注意:在c语言中,所有数组的下标都从0开始。
例子:
#define MAX_SIZE 100
float sum(float [], int);
float input[MAX_SIZE],answer;
int i;
void main(void)
{
for(i=0;i<MAX_SIZE;i++)
input[i]=i;
answer=sum(input,MAX_SIZE);
printf("The sum is: %f\n",answer);
}
float sum(float list[], int n)
{
int i;
float tempsum=0;
for(i=0;i<n;i++)
tempsum+=list[i];
return tempsum;
}
通过地址访问一维数组:
void print1(int *ptr, int rows)
{
/*print out a one-dimensional array using a pointer*/
int i;
printf("Address Contents\n");
for(i=0;i<rows;i++)
printf("%8u%5d\n",ptr+i,*(ptr+i));
printf("\n");
}
%u 无符号10进制整数
2.2 结构与共用体
数组是相同类型数据的聚集。
例子:
(1).
struct{
char name[10];
int age;
float salary;
}person;
(2).检验结构间相等的函数
int humans_equal(human_being person1,human_being person2)
{
/*return TRUE if person1 and person2 are the same human being otherwise return FALSE*/
if(strcmp(person1.name,person2.name))
return FALSE;
if(person1.age!=person2.age)
return FALSE;
if(person1.salary!=person2.salary)
return FALSE;
return TRUE;
}
(3).一个结构内嵌入另一个结构
typedef struct{
int month;
int day;
int year;
}date;
typedef struct human_being{
char name[10];
int age;
float salary;
date dob;
};
2.2.2 共用体
共用体的声明类似于结构,但是其成员域必须共享同一存储空间。
例子:
typedef struct sex_type{
enum tag_field{female,male} sex;
union{
int children;
int beard;
} u;
};
typedef struct human_being{
char name[10];
int age;
float salary;
date dob;
sex_type sex_info;
};
human_being person1, person2;
2.2.3 结构体的内部实现
一个结构或共用体类型对象的大小是表示其最大分量所必需的存储单元的数目,其中也包含必需的填塞。结构必须开始并结束于相同类型的内存分界处。
2.2.4 自引用结构
自引用结构是一种特殊的结构,它的一个或多个分量是指向其自身的指针,通常需要动态存储管理程序来显示地分配或释放内存。
例子:
typedef struct list{
char data;
list *link;
};
2.3 ADT多项式
数组不仅是一种数据结构,也可以用来实现其他抽象数据型。
void padd(int starta,int finisha,int startb,int finishb,int *startd,int *finishb)
{
/*add A(x) and B(x) to obtain D(x)*/
float coefficient;
*startd=avail;
while(starta<=finisha&&startb0<=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++;
}
/*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;
}
2.4ADT稀疏矩阵
例子:1.稀疏矩阵的转置
//稀疏矩阵的装置
void transpose(term a[],term b[])
/*b是a的装置*/
{
int n,i,j,currentb;
n=a[0].value; /*元素总行*/
b[0].row=a[0].col; /*b的行数=a的列数*/
b[0].col=a[o].row; /*b的列数=a的行数*/
b[0].value=n;
if(n>0){/*非零矩阵*/
currentb=1;
for(i=0;i<a[0].col;i++)
/*按a的列装置*/
for(j=1;j<=n;j++){
/*找到当前列的所有元素*/
b[currentb].row=a[j].col;
b[currentb].col=a[j].row;
b[currentb].value=a[j].value;
currentb++;
}
}
}
2.稀疏矩阵的快速转置
//稀疏矩阵的快速转置
void fast_transpose(term a[],term b[])
{
/*将a的转置矩阵存放于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){/*非零矩阵*/
for(i=0;i<num_cols;i++)
row_terms[i]=0;
for(i=0;i<=num_terms;i++)
row_terms[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];
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;
}
}
}