数据结构-向量

遍历用到了函数对象,还有一种函数指针的做法,我都不会...回来再说

构造,析构,和复制

Vector(int c = DEFAULT_CAPACITY) {          //默认构造函数
    _elem = new T[_capacity = c];
    _size = 0;
}
template<typename T>                                      //复制元素
void Vector<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++];
    }
}
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);
}

递增式扩容和加倍式扩容

加倍式扩容时间复杂度更低,但是空间利用率不高。递增式扩容相反。
分摊复杂度衡量算法更好,好于平均复杂度

template<typename T>
void Vector<T>::expand() {
    if (_size < _capacity)return;
    _capacity = max(_capacity, DEFAULT_CAPACITY);
    T* oldElem = _elem;
    _elem = new T[capacity <<= 1];                 //加倍式扩容
    _elem = new T[capacity += INCREMENT];          //递增式扩容
    for (int i = 0;i < _size;i++) {
        _elem[i] = _oldElem[i];
    }
    delete[]oldElem;
}

无序向量

寻秩访问,重载[]

template<typename T>                            //向量的寻秩访问
T& Vector<T>::operator[](Rank r) const{
    return _elem[r];
}

插入

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[i] = e;
    _size++;
    return r;     //返回秩
}

区间删除

template<typename T>                          //区间删除。  只能从前向后删
int Vector<T>::remove(Rank lo, Rank hi) {
    if (lo == hi)return 0;
    while (hi < _size) {
        _elem[lo++] = _elem[hi++];
        shrink();                      //若有必要,缩容
    }
    return hi - lo;
}

单元素删除
用到了remove(Rank lo,Rank hi)

template<typename T>                       //删除单元素
int Vector<T>::remove(Rank r) {
    T e = _elem[r];              //备份元素
    remove(r, r + 1);
    return e;
}

查找

template<typename T>                              //查找      从后向前查找
Rank Vector<T>::find(T const& e, Rank lo, Rank hi) {
    while ((lo < hi--) && e != _elem[hi]);              //判断是否找到了e
    return hi;                                          //观察hi是否合法,来判断
}

唯一化算法
无序向量的唯一化

template<typename T>                        //唯一化算法,通过 单调性(最多迭代O(n)) 和 不变性(元素i的前缀总是互异的) 证明 正确性。
int Vector<T>::deduplicate() {
    int oldSize = _size;
    Rank i = 1;
    while (i < _size) {
        (find(_elem[i], 0, i) < 0) ?         //调用find()函数
            i++                              //没找到i+1;
            : remove(i);                     //找到了删除i;
    }
    return oldsize - _size;                 //返回删除元素总数。
}

遍历,,,这里我并不会实现,,,用到了函数对象

template<typename T>template<typename VST>           //函数对象的方式实现遍历 ***不会啊***
void Vector<T>::traverse(VST& visit) {
    for (int i = 0;i < _size;i++) {
        visit(_elem[i]);
    }
}

有序向量

判断是否有序

template<typename T>                                 //判断是否有序
int Vector<T>::disordered()const {
    int n = 0;
    for (int i = 1;i < _size;i++) {
        n += (_elem[i - 1] > _elem[i]);         //检查逆序对数量
    }
    return n;
}

有序向量的唯一化
有序向量的唯一化算法可以很好的优化

template<typename T>                  //有序vector的唯一化    ***复杂度是O(n*n)***和无序的一样***
int Vector<T>::uniquify() {
    int oldsize = _size;
    int i = 0;
    while (i < _size - 1) {
        (_elem[i] == _elem[i + 1]) ?
            remove(i + 1) :                     //运用了remove
            i++;
    }
    return oldsize - _size;
}

复杂度为O(n)的唯一化算法

template<typename T>                   //针对有序向量优化过的算法
int Vector<T>::uniquefy() {
    Rank i = 0, j = 0;                 //i维护新向量的长度
    while (++j < _size) {
        if (_elem[i] != _elem[j])_elem[i++] = elem[j];
    }
    _size = ++i;                          //最终的Vector大小
    return j - i;                         //删除的元素个数
}

猜你喜欢

转载自www.cnblogs.com/iwannazhe123/p/12382493.html
今日推荐