数据结构与算法 笔记 第二章
(1)元素访问
v.get( r ) , v.put( r , e )
重载运算符 [ ]
template <typename T>
T & Vector <T>::operator[](Rank r)
const {
return _elem[r];
}
//重载后可被赋值 : V[ r ] = ( T )( 2* x + 2 );
//也可赋值 : T = V[ r ] + U[ s ] * W[ t ] ;
(3)元素插入
template <typename T>
Rank Vector<T>::insert(Rank r,T const & e){
expand(); //若超过容量就扩展
for(int i = _size;i > r;i--)
_elem[i] = _elem[i-1]; //最后一个肯定是空的,避免覆盖
_elem[r] = e;
_size++;
retuen;
}
//记得把非空部分 + 1
(4)区间删除
template <typename T>
T Vector<T>::remove(Rank low,Rank high){
if(low == high)
return 0;
while(high < n--)
_elem[low++] = _elem[high--];
_size = low; //更新数组的大小
shrink(); //把后面没用的空间删掉
return high - low;
}
//把 high 之后的元素,从前向后覆盖 low 之后的元素
//若从后向前覆盖,_elem[high--] = _elem[high++] 可能元素不足以覆盖掉删除元素
//到时候中间会空一块?没有办法重新规定大小,shrink() 不好用
(5)单元素删除(区间删除的特殊情况)
template <typename T>
T Vector<T>::remove(Rank r){//模板类,会根据参数自行选择
T e = _elem[r];//e取的是元素本身,而不是秩,返回T
remove(r,r+1);
return e;
}
思考:
若反过来利用单元素删除来进行区间删除
复杂度可达 O(n²),因为要进行(high-low)=n 次
每次移动(_size - high)= n 个
(6)唯一性算法
把数组分为三个部分,前缀 目标元素 后缀
以目标元素为比较对象,遍历整个数组,查找是否有相同元素 find(x)
若有相同元素:删除目标元素,移项
若无相同元素:目标元素移向下一位
复杂度分析:
find()每次需要 n 的时间
对目标元素的遍历也是 n 的时间,T(n²)拒绝
V.sort().uniquify()
T(nlogn)
(7)遍历操作 visit
法一:函数指针 //局部性修改
*visit作为函数指针
?/这个没太懂…
template <typename T>
void Vector<T>::traverse(void (*visit)(T&)){
for(int i=0;i<_size;i++)
visit (_elem[i]);
}
法二:函数对象 //全局性修改
template <typename T>
template <typename VST>
void Vector<T>::traverse(VST&visit){
for(int i=0;i<_size;i++)
visit(_elem[i]);
}