线性群体中的元素次序与其位置关系是对应的。在线性群体中,又可按照访问元素的不同方法分为直接访问、顺序访问和索引访问。
对可直接访问的线性群体,我们可以直接访问群体中的任何一个元素,而不必首先访问该元素之前的元素。
对顺序访问的线性群体,只能按元素的排列顺序从头开始依次访问各个元素。
还有两种特殊的线性群体--栈和队列。
2、直接访问群体---数组类
针对静态数组的缺陷,我们来设计一个动态数组类模板Array,它由任意多个位置连续的,类型相同的元素组成,其元素个数可在程序运行是改变。
a、数组类
#ifndefARRAY_CLASS#defineARRAY_CLASS
#include
#include
usingnamespacestd;
#ifndefNULL
constintNULL=0;
#endif//NULL
//错误类型集合,共有三种类型的错误:数组大小错误、内存分配错误和下标越界e
numErrorType{invalidArraySize,memoryAllocationError,indexOutOfRange};
//错误信息
char*errorMsg[]={"Invalidarraysize","Memoryallocationerror","Invalidindex:"};
template
classArray{
private:T*alist;//T类型指针,用于存放动态分配的数组内存首地址
intsize;//数组大小
voidError(ErrorTypeerror,intbadIndex=0)const;//错误处理函数
public:Array(intsz=50);//构造函数
Array(constArray
~Array(void);//析构函数
Array
T&operator[](inti);//重载"[]",使Array对象可以起到C++普通数组的作用
operatorT*(void)const;//重载T*,使Array对象可以起到C++普通数组的作用
intListSize(void)const;//取数组的大小
voidResize(intsz);//修改数组的大小
};
//以下为类成员函数的定义
//模板函数Error实现输出错误信息的功能
voidArray
{cout< if(error==indexOutOfRange) cout< cout< //构造函数 template {if(sz<=0)//sz为数组大小 Error(invalidArraySize); size=sz; alist=newT[size];//动态分配size个T类型的元素空间 if(alist==NULL) //如果分配内存不成功,输出错误信息 Error(memoryAllocationError);}; //析构函数 template {delete[]alist;} //拷贝构造函数 template {//从对象X取得数组大小,并赋值给当前对象的成员 intn=X.size; size=n;//为对象申请内存并进行出错检查 alist=newT[n];//动态分配n个T类型的元素空间 if(alist==NULL)//如果分配内存不成功,输出错误信息 {Error(memoryAllocationError);}//从对象X复制数组元素到本对象 T*srcptr=X.alist;//x.alist是对象X的数组首地址 T*destptr=alist;//alist是本对象中的数组首地址 while(n--)*destptr++=*srcptr++; }//重载"="运算符,将对象rhs赋值给本对象。实现对象的整体赋值 template {intn=rhs.size;//取rhs的数组大小//如果本对象中数组大小与rhs不同,则删除数组原有内存,然后重新分配 if(size!=n) {delete[]alist;//删除数组原有内存 alist=newT[n];//重新分配n个元素的内存 Error(memoryAllocationError); size=n;//记录本对象的数组大小 } //从rhs向本对象复制元素 T*destptr=alist; T*srcptr=rhs.alist; while(n--) *destptr++=*srcptr++; return*this;//返回当前对象的引用 //重载下标运算符,实现与普通数组一样通过下标访问元素,并且具有越界检查功能 template { if(n<0||n>size-1)//检查下标是否越界 Error(indexOutOfRange,n); returnalist[n];//返回下标为n的数组元素 //重载指针转换运算符,将Array类的对象名转换为T类型的指针,指向当前对象中的私有数组, //因而可以像使用普通数组首地址一样使用Array类的对象名 template {returnalist;//返回当前对象中私有数组的首地址} //取当前数组的大小 template //将数组大小修改为sz template {if(sz<=0)//检查是否sz<=0 if(sz==size)//如果指定的大小与原有大小一样,什么也不做 return; T*newlist=newT[sz];//申请新的数组内存 if(newlist==NULL)//测试申请内存是否申请成功 intn=(sz<=size)sz:size;//将sz与size中较小的一个赋值给n//将原有数组中前n个元素复制到新数组中 T*srcptr=alist;//原数组alist的首地址 T*destptr=newlist;//新数组newlist的首地址 while(n--)//复制数组元素 {*destptr++=*srcptr++;} delete[]alist;//删除原数组 alist=newlist;//使alist指向新数组 size=sz;//更新sz}#endif//ARRAY_CLASS zhishu.cpp #include #include"shuzu.h" intmain() Array intn; intprimecount=0,i,j; cout<<"Enteravalue>=2asupperlimitforprimenumbers:"; cin>>n; A[primecount++]=2;//2是一个质数 for(i=3;i //如果质数表满了,便再申请分配10个元素的空间 if(primecount==A.ListSize()) {A.Resize(primecount+10);} //大于2的偶数不是质数,因此略过本次循环的后继部分,进入下一次循环