预备知识
模板
定义函数模板
如果写一个比较两参数大小的函数,根据参数的数据类型,我们需要写很多重复的
int compare(const int &v1,const int &v2);
int compare(const string &v1,const string &v2);
所以定义一个模板
template <typename T>
将模板使用到函数中
int compare(const T &v1,const T &v2);
编译器会根据函数参数推断模板类型,不同类型的参数会生成不同版本的函数
template <typename T>
int compare(const T &v1,const T &v2)
{
if (v1<v2)
cout<<"v1小于v2"<<endl;
if (v1>v2)
cout<<"v1大于v2"<<endl;
return 0;
}
在函数中使用
compare(1,2);
vector<int> vec1{1,2,3},vec2{4,5,6};
compare(vec1,vec2);
定义类模板
在定义时使用类模板来生成类的蓝图,在使用时需要指出类型<>
vector本身是个类模板,使用模板需要指出一些额外信息来确定模板实例化成什么类
即在模板后加<>,在括号内放入信息
template <typename DataType>class SeqList{
}
类模板内成员函数和成员变量都可以使用模板参数
顺序表
定义顺序表类模板及其基本操作
顺序表应有表尾插入元素,删除指定元素,返回指定位置元素,修改指定位置元素的基本操作
还要设置默认顺序表大小,在构造函数中检查赋予的顺序表大小,如果合法则分配相应大小的内存。在析构函数中回收内存空间。
const int defaultSize=10; //设置默认顺序表大小
template <typename DataType>class SeqList //顺序表中含有不确定类型的数据,所以使用模板类
{
public:
//构造函数
SeqList(int size=defaultSize)
{
if(size>0) //检查赋予的顺序表大小,如果合法则分配相应大小的内存
{
maxSize=size;
length=0;
elements=new DataType[maxSize]; //分配内存大小
for(int i=0;i<maxSize;i++)
elements[i]=NULL;
}
}
//析构函数s
~SeqList()
{
delete [] elements; //回收内存空间
}
bool insertElement(DataType data); //表尾插入元素
bool deleteElement(int location); //删除指定位置元素
DataType getElement(int location); //返回指定位置元素
bool changeElement(int location,DataType newdata); //修改指定位置元素
int getLength()
{
return length;
}
private:
static const int defaultSize=10;
int maxSize;
DataType *elements; //元素类型不确定,所以设为模板类型
int length; //顺序表有效长度
};
顺序表插入
- 如果顺序表已满,提示错误
- 如果未满,在表尾插入新元素,有效长度加1
template <typename DataType> bool SeqList<DataType>::insertElement(DataType data)
{//类模板的成员函数在定义时 1.要加上类名<模板参数>:: 2.加入模板定义
int currentIndex=length; //记录新元素插入位置
if(length>maxSize) //判断是否满
{
return false; //满了报错
}
else
{
elements[currentIndex]=data; //在当前位置插入
length++; //有效长度+1
return true;
}
}
顺序表删除指定位置元素
按照索引,将i之后位置的元素向前移动一位即可
template <typename DataType> bool SeqList<DataType>::deleteElement(int location)
{
if(location>=length||location<0)
{
return false;
}
else
{
for(int i=location;i<length;i++)
{
elements[i]=elements[i+1]; //将指定位置后元素依次向前覆盖一位
}
length--; //有效长度减一
return true;
}
}
获取指定位置元素
template <typename DataType> DataType SeqList<DataType>::getElement(int location)
{
if(location>length||location<0) //判断位置是否合法
{
cout<<"参数无效"<<endl;
return 0;
}
else
{
return elements[location]; //返回指定位置元素
}
}
修改指定位置元素
template <typename DataType> bool SeqList<DataType>::changeElement(int location,DataType newdata)
{
if(location>=length||location<0) //判断位置是否合法
{
cout<<"参数无效"<<endl;
return false;
}
else
{
elements[location]=newdata;
return true;
}
}
在main()函数中操作
int main()
{
SeqList<int> list(10); //建立顺序表
for(int i=0;i<10;i++)
list.insertElement(i*10); //插入元素
for(int i=0;i<list.getLength();i++) //查找元素
cout<<list.getElement(i)<<" ";
cout<<endl;
list.deleteElement(3); //删除元素
for(int i=0;i<list.getLength() ;i++) //显示删除后
cout<<list.getElement(i)<<" ";
cout<<endl;
list.changeElement(3,55);
for(int i=0;i<list.getLength() ;i++) //显示修改后
cout<<list.getElement(i)<<" ";
cout<<endl;
return 0;
}