接口与实现
基础
向量ADT
操作实例
构造与析构函数
复制
可扩充向量
静态空间管理
动态空间管理
扩容算法实现
template<typename T>
void Vector<T>::expand() { //向量空间不足时扩容
if (_size < _capacity) return; //尚未满员时,不必扩容
_capacity = max(_capacity, DEFAULT_CAPACITY); //不低于最小容量
T* oldElem = _elem; _elem = new T[_capacity <<= 1]; //容量加倍
for (int i = 0; i < _size; i++) //复制原向量内容
_elem[i] = oldElem[i] //T为基本类型,或已重载赋值操作符‘=’
delete[]oldElem; //释放原空间
}
得益于向量的封装,尽管扩容之后数据区的物理地址有所改变,却不致出现野指针
为何必须采用“容量加倍”的策略呢?其它策略是否可行?
加倍式扩容
空间换时间!
分摊复杂度
无序向量
无序向量:向量的最基本元素
模板的基本概念
循迭访问
插入
区间删除
template<typename T> //删除区间[lo,hi),0<=lo<=hi<=size
int Vector<T>::remove(Rank lo, Rank hi) { //O(n-hi)
if (lo == hi)return 0; //出于效率考虑,单独处理退化情况
while (hi < _size)_elem[lo++] = _elem[hi++]; //[hi,_size)顺次前移hi-lo位
_size = lo; shrink(); //更新规模,若有必要则缩容
return hi - lo; //返回被删除元素的数目
}
查找
- 无序向量:T为可判等的基本类型,或已重载操作符“==”或“!=”
- 有序向量:T为可比较的基本类型,或已重载操作符“<”或“>”
template<typename T> //0 <= lo < hi <= _size
Rank Vector<T>::find(T const& e, Rank lo, Rank hi)const {
//O(hi - lo) = O(n),在命中多个元素时可返回秩最大者
while ((lo < hi--) && e != _elem[hi]); //逆向查找
return hi; //hi < lo意味着失败;否则hi即命中元素的秩
} //Excel::match(e,range,type)
输入敏感(input-sensitive):最好O(1),最差O(n)