您的位置:首页 > 其它

无序向量Vector

2015-06-09 19:06 316 查看
向量vector

1、AbstractData Type(ADT)抽象数据类型:数据模型上定义的一种操作。Data structure数据结构:基于某种特定语言,实现ADT的一整套算法。向量是数组的抽象和泛化,有一组元素按线性顺序封装而成。

ADT操作接口:





2、vector模板类

(1)基于复制的构造

template<typename T>
voidVector<T>::copyFrom(T* const A,Rank lo,Rank hi)
{
_elem=new T[_capacity=2*(hi-lo)];//申请空间
_size=0;
while(lo<hi)
_elem[_size++]=A[lo++];
}
一般都以左闭右开,A[lo,hi),所以总共长度是hi-lo,hi不属于vector的,可以当做哨兵使用。



(2)扩容expand()

上溢overflow,下溢underflow.动态空间管理:在即将发生上溢时,适当地扩大内部数组的容量。

template<typename T>
voidVector<T>::expand()
{
if(_size<_capacity) return;
T *oldElem=_elem; //备份
_elem=new T[capacity<<=1]; //容量加倍
for(int i=0;i<_size;i++)
_elem[i]=oldElem[i];
delete [] oldElem; //释放空间
}
为什么需要容量加倍呢?下图是递增扩容和加倍扩容。



平均复杂度average/expected complexity,是独立的过程。

分摊分析amortized complexity,连续的操作,更加贴近实际。

3、无序向量

template <typename T> Vector{...};定义一系列vector:

例如Vector<int> myVector… Vector<BinTree > myVector…

(1)元素访问:重载操下标操作符[]

template<typename T>
T&Vector<T>::operator[](Rank r)const
{
return _elem[r];
}

(2)插入元素insert( )

template<typename T> //把e作为秩r的元素插入
RankVector<T>::insert(Rank r,T const &e)
{
expand(); //扩容
for(int i=_size;i>r;i--)
_elem[i]=_elem[i-1]; //将元素往后移动,直到移动到r
_elem[r]=e;_size++;
return r;
}



(3) 区间删除remove(),复杂度O(n-hi)

template <typename T> //删除区间[lo,hi)

int Vector<T>::remove(Rank lo,Rank hi)

{

if(lo==hi)  return 0;

while(hi<_size) _

elem[lo++]=_elem[hi++]; //顺次往前移动hi-lo位

_size=lo;shrink();

return hi-lo;

}

(4)单元素删除remove(),复杂度为O(n-r)

template <typename T>

T Vector<T> ::remove(Rank r)

{

T e=_elem[r];

remove(r,r+1);

return e;

}

如果区间删除调用单元素删除的话,理论上是可以的,但是复杂度的话每次调用都需要O(n-r),这样级数相加,最后区间删除的复杂度有可能是O(n2)。

(5)查找操作find无需判断一般只支持判等操作,有序向量支持比较操作

template <typename T>  //查找在区间lo,hi之间的元素,靠近hi

Rank Vector<T>::find(T const &e,Rank lo,Rank hi) const

{

while((lo<hi--)&&(e!=_elem[hi]));//持续到成功为止才退出循环

return hi;

}最好O(1),最差O(n)

(6)唯一化deduplicate( )去重操作:经过查找函数,如果有的话删除

template<typename T>
intVector<T>::deduplicate()
{
int oldSize=_size;
Rank i=1;
while(i<_size)
(find(_elem[i],0,i)<0)?i++:remove(i);//如果找到元素则删除,否i++
return oldSize-_size; //返回删除的元素个数
}
对于find,remove每次迭代最多是O(n),所以最坏的复杂度是O(n2)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: