向量的抽象数据类型
- 向量:由同一种数据类型的数据元素组成的线性表,因此向量的逻辑结构和一般线性表的逻辑结构是相同的。
- 向量的存储结构:向量元素按照它们之间的关系排成一个线性序列 a0, a1, … , an-1,即 n 个向量元素的序号为 0 ~ n-1,这使得向量采用数组存储结构更自然,处理更方便。数组元素物理上的相邻关系隐含地提现了向量元素逻辑上的相邻关系。
随机存储结构:只要知道了整个向量的存储始地址、某向量元素的序号和每个向量元素所占的空间的大小,就可以立即求出该向量元素的存储地址,而且求任何一个向量的存储地址所花费的时间都相等。
- 向量的抽象模型的实现:向量的抽象模型和线性表的抽象模型是相同的,只是在实现的方式上略有差异。
#ifndef _Vector_H
typedef int ElementType;
enum boolean {FALSE,TRUE};
typedef enum boolean Bool;
struct vector{
ElementType *elements;
int ArraySize;
int VectorLength;
};
typedef struct vector Vector;
void GetArray(Vector *); /*申请向量的存储空间*/
void InitVector(Vector *, int size); /*初始化一个空向量*/
ElementType GetNode(Vector *V, int i); /*取向量的第 i 个表目*/
void FreeVector(Vector *); /*释放向量的存储空间*/
int Find(Vector *, ElementType); /*在向量中查找*/
Bool Remove(Vector *, int i); /*删除向量的第 i 个表目*/
#endif // _Vector_H
注:在具体编写头文件的时候,需要在头文件把具体的ElementType定义出来,或者用其他基本数据类型代替。
- 具体代码实现:
void GetArray(Vector *V){
V->elements = (ElementType *)malloc(sizeof(ElementType) * V->ArraySize);
if(V->elements == NULL)
printf("Memory Allocation Error!\n");
}
void InitVector(Vector *V, int size){
if(size <=0)
printf("Invalid Array Size\n");
else{
V->ArraySize = size;
V->VectorLength = 0;
GetArray(V);
}
}
ElementType GetNode(Vector *V, int i){
return (i<0||i>=V->VectorLength)?NULL:V->elements[i];
}
void FreeVector(Vector *V){
free(V->elements);
}
int Find(Vector *V, ElementType x){
int i;
for(i=0;i<V->VectorLength;i++)
if(V->elements[i]==x) return i;
return -1;
}
Bool insert(Vector *V,ElementType x, int i){
int j;
if(V->VectorLength == V->ArraySize){
printf("overflow\n");
return FALSE;
}
else if(i<0||i>V->VectorLength){
printf("position error\n");
return FALSE;
}
else{
for(j=V->VectorLength-1;j>=i;j--)
V->elements[j+1]=V->elements[j];
V->elements[i]=x;
V->VectorLength++;
return TRUE;
}
}
Bool Remove(Vector *V, int i){
int j;
if(V->VectorLength == 0){
printf("Vector is empty\n");
return FALSE;
}
else if(i<0||i>V->VectorLength-1){
printf("position error\n");
return FALSE;
}
else
for(j=i;j<V->VectorLength-1;j++)
V->elements[j]=V->elements[j+1];
V->VectorLength--;
return TRUE;
}
注:
(1)在线性表数据元素的插入或者删除之前都需要判断位置与数组长度的关系。插入要考虑线性表是否为满表,删除需要考虑线性表是否为空表。
向量的应用
1.求集合的“并运算”和“交运算”
【并运算】
Vector *Union(Vector * Va,Vector * Vb)
/*把向量Va和Vb中的元素合并到Vc中,重复元素只保留一个*/
{
int m,n,i,j,k;
ElementType x;
/*获取空向量Vc的存储空间*/
Vector Vc = (Vector *)malloc(sizeof(Vector));
/*初始化一个空向量*/
n = Va->VectorLength;
m = Vb->VectorLength;
InitVector(Vc,m+n);
/*把向量Va的元素存插入到Vc中*/
j=0;
for(i=0;i<n;i++){
x = GetNode(Va,i);
Insert(Vc,x,j);
j++;
}
/*将Vb中有,Va中没有的元素插入到Vc中*/
for(i=0;i<m;i++){
x = GetNode(Vb,i);
k = Find(Va,x);
if(k == -1){
Insert(Vc,x,j);
j++;
}
return Vc;
}
}
这里会出现一个警告:
warning: c