向量是数组的扩张。二者同是采用顺序存储方式的数据类型,所不同的是向量的封装性好、抽象度高,具有更好的安全性能与更多的操作接口。
在C++环境下,向量模板类可以如下定义:
typedef int Rank //定义秩
#define DEFUALT_CAPACITY //定义默认容量
Template <typename T>
class vector //向量模板类
{
private:
Rank _size;
int _capacity;
T* _elem;
protected:
/*内部函数*/
public:
/*构造函数*/
/*析构函数*/
/*只读接口*/
/*可写接口*/
/*遍历接口*/
/*其他……*/
};
/*--向量的基本操作--*/
构造函数和析构函数是类的基本方法,其实现如下:
vector(int c = DEFUALT_CAPACITY) //默认构造函数
{ _elem = new T[_capacity = c]; _size = 0; }
vector(T* const A, Rank lo, Rank hi) //复制函数区间
{ copyfrom (A, lo, hi); }
vector(vector<T> const & V, Rank lo, Rank hi) //复制向量区间
{ copyfrom (V._elem, lo, hi); }
vector(vector<T> const & V) //复制向量区间
{ copyfrom (V._elem, 0, V._size); }
~vector() //析构函数
{ delete [] _elem; }
上面的构造函数所使用的复制函数实现如下:
void vector<T>::copyfrom(T* const A, Rank lo, Rank hi)
{
_elem = new T[2*(hi - lo)]; //分配足够大的存储空间
_size = 0; //规模清空
while (lo < hi) //将A[lo, hi)元素逐个
_elem[size++] = A[lo++]; //复制到_elem[0, hi - lo)中
}
/*--向量的容量调整--*/
为了应对不同实例对于数据存储规模的要求,我们设置了默认容量值以保证向量规模。在这里,整型变量_capacity用来记录向量的最大容量,而_size则用于记录向量的实际长度。由于实例中向量的元素可能会有大量的变动,因此我们需要定义扩容及缩容操作以方便及时的调整容量从而既能保证需求,又能避免浪费。扩容操作的实现如下:
void vector<T>::expand()
{
if (_size < _capacity) return; //尚未满员时,不必扩容
_capacity = max(_capaticy, DEFUALT_CAPACITY); //确保容量不小于默认值
T *old_elem = elem; //记录原有数据
elem = new T[_capacity *= 2]; //容量加倍
for (int i = 0; i < _size; i++)
_elem[i] = old_elem[i]; //复制原向量的内容
delete [] old_elem; //释放原空间
}
相应的可定义缩容操作,其实现如下:
void vector<T>::shrink()
{
if (_size*2 >= _capacity) return; //尚未缺半时,不必缩容
T *old_elem = _elem; //记录原有数据
_elem = new T[_capacity /= 2]; //容量减半
for (int i = 0; i < _size; i++)
_elem[i] = old_elem[i]; //复制原向量的内容
delete [] old_elem; //释放原空间
}
/*--无序向量的重要接口--*/
访问向量元素时,可像访问数组一样使用下标,或称为循秩访问。这需要重载下标操作符"[]"
T & vector<T>::operator[](Rank r) const { return _elem[r]; }
插入单元素:
Rank vector<T>::insert(Rank r, T *e) // 在秩为r处插入元素e
{
expand();
for (int i = _size; i > r; i--)
_elem[i] = _elem[i - 1];
_elem[r] = e;
_size++;
return r;
}
删除整区间:
int vector<T>::remove(Rank lo, Rank hi) //删除区间[lo, hi)
{
if ( hi <= lo ) return 0; // 判别删除对象是否为空
while ( hi < _size)
_elem[lo++] = _elem[hi++]; //[lo, hi)顺次前移
_size = lo;
shrink(); //若有必要,则更新规模
return ( hi - lo );
}
删除单元素:
T vector<T>::remove(Rank r)
{
T e = _elem[r]; //备份欲删除元素
remove(r, r+1); //调用区间删除函数
return e; //返回被删除元素的值
}