向量是具有线性次序的一组元素构成的集合。

特点:查找快,增删慢。

 

头文件vector.h

typedef int Rank;             //
#define DEFAULT_CAPACITY (3)  //默认的初始容量


template <typename T> class Vector{
protected:
    //规模,容量,数据区
    Rank _size;
    int _capacity;
    T *_elem;
    
    void copyFrom(T const* A,Rank lo,Rank hi);  //复制数组区间A[lo,hi)
    void expand(); //空间不足时扩容
    void shrink(); //装填因子过小时压缩
    bool bubble(Rank lo,Rank hi); //扫描交换
    void bubbleSort(Rank lo,Rank hi);  //冒牌排序算法
    Rank max(Rank lo,Rank hi); //选取最大元素
    void selectionSort(Rank lo,Rank hi); //选择排序算法
    void merge(Rank lo,Rank mi,Rank hi); //归并算法
    void mergeSort(Rank lo,Rank hi);  //归并排序算法
    Rank partition(Rank lo,Rank hi); //轴点构造算法
    void quickSort(Rank lo,Rank hi); //快速排序算法
    void heapSort(Rank lo,Rank hi); //堆排序
    
public:
    //构造函数
    Vector(int c = DEFAULT_CAPACITY, int s = 0,T v = 0) {
        _elem = new T[_capacity = c];
        for (_size = 0; _size < s; _elem[_size++] = v);
    }
    
    Vector(T const* A,Rank n){  //数组整体复制
        copyFrom(A, 0, n);
    }
    
    Vector(T const* A,Rank lo,Rank hi){  //区间
        copyFrom(A, lo, hi);
    }
    
    Vector(Vector<T> const& v) {
        copyFrom(v._elem, 0, v._size);
    }
    
    Vector(Vector<T> const& v,Rank lo,Rank hi){
        copyFrom(v._elem, lo, hi);
    }
    
    ~Vector(){
        delete [] _elem;  //释放内存空间
    }
    
    //只读访问接口
    //规模
    Rank size() const {
        return _size;
    }
    
    //判空
    bool empty() const {
        return !_size;
    }
    
    int disordered() const;  //判断向量是否已排序
    
    Rank find(T const& e){      //无序向量整体查找
        return find(e, 0, _size);
    }
    
    Rank find(T const& e,Rank lo,Rank hi) const; //无序向量区间查找
    
    Rank search(T const& e) const {
        return (0 >= _size) ? -1 : search(e, 0, _size);
    }
    
    Rank search(T const& e, Rank lo, Rank hi) const;   //有序向量区间查找
    
    //可写访问接口
    T& operator[](Rank r) const;
    Vector<T> & operator=(Vector<T> const&);
    T remove(Rank r);
    int remove(Rank lo,Rank hi);
    Rank insert(Rank r,T const& e);
    Rank insert(T const& e) {
        return insert(_size, e);
    }
    
    void sort(Rank lo,Rank hi);  //对[lo,hi]排序
    void sort() {
        sort(0, _size);
    }
    
    void unsort(Rank lo,Rank hi); //对[lo,hi]置乱
    void unsort() {
        unsort(0, _size);
    }
    
    int deduplicate();  //无序去重
    int uniquify();  //有序去重
    //遍历
    void traverse(void (*)(T&)); //遍历(使用函数指针,只读或局部性修改)
    template <typename VST> void traverse(VST&);  //遍历(使用函数对象,可全局性修改)
    
};

实现文件Vector.cpp

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++]; //复制至_elem[0,hi-lo)
    }
}

//向量空间不足时扩容
template <typename T> void Vector<T>::expand() {
    if (_size < _capacity) {
        return;
    }
    
    if (_capacity < DEFAULT_CAPACITY) {
        _capacity = DEFAULT_CAPACITY;  //不低于最低容量
    }
    
    T *oldElem = _elem;
    _elem = new T[_capacity <<= 1];  //容量加倍
    for (int i = 0; i < _size; i++) {
        _elem[i] = oldElem[i];
    }
    
    delete [] oldElem;  //释放原空间
}

//装填因子过小时压缩向量所占空间
template <typename T> void Vector<T>::shrink() {
    if (_capacity < DEFAULT_CAPACITY << 1) {
        return;      //不致收缩到DEFAULT_CAPACITY以下
    }
    
    if (_size << 2 > _capacity) {
        return;      //以25%为界
    }
    
    T *oldElem = _elem;
    _elem = new T[_capacity >>= 1];  //容量减半
    for (int i = 0; i < _size; i++) {
        _elem[i] = oldElem[i];
    }
    delete [] oldElem; //释放原空间
}


template <typename T> Vector<T>& Vector<T>::operator=(const Vector<T> &V){
    if (_elem) {
        delete [] _elem;  //释放原有内容
    }
    copyFrom(V._elem, 0, V.size());  //整体复制
    return *this;
}

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

//等概率随机置乱区间[lo,hi)
template <typename T> void Vector<T>::unsort(Rank lo, Rank hi) {
    T* V = _elem+lo;
    for (Rank i = hi - lo; i > 0; i--) {
        std::swap(V[i-1], V[rand() % i]);
    }
}

template <typename T> Rank Vector<T>::find(T const&e, Rank lo, Rank hi) const {
    while ( (lo < hi--) && (e != _elem[hi]) );
    
    return hi;  //若hi < lo,则意味着失败;否则hi即命中元素的秩
}

template <typename T> Rank Vector<T>::insert(Rank r, const T &e) {
    expand();  //若有必要,扩容
    for (int i = _size; i > r; i--) {
        _elem[i] = _elem[i-1];
    }
    _elem[r] = e;
    _size++;
    return r;
}

template <typename T> int Vector<T>::remove(Rank lo, Rank hi) {
    if (lo == hi) {
        return 0;   //出于效率考虑,单独处理退化情况,比如remove(0,0)
    }
    
    while ( hi < _size) {
        _elem[lo++] = _elem[hi++];
    }
    
    _size = lo;
    shrink();
    return hi - lo;
}

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

//删除无序向量中的重复元素(高效版)
template <typename T> int Vector<T>::deduplicate() {
    int oldSize = _size;
    Rank i = 1;
    while ( i < _size) {
        ( find(_elem[i], 0, i) < 0) ? i++ : remove(i);
    }
    
    return oldSize - _size;
}

//借助函数指针机制
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]);
    }
}


//返回向量中逆序相邻元素对的总数
template <typename T> int Vector<T>::disordered() const {
    int n = 0;
    for (int i = 0; i < _size; i++) {
        if (_elem[i-1] > _elem[i]) {
            n++;
        }
    }
    
    return n;
}

/*
 //有序向量重复元素剔除算法(低效版)
 template <typename T> int Vector<T>::uniquify() {
 int oldSize = _size;
 int i = 1;
 while (i < _size) {
 _elem[i-1] == _elem[i] ? remove(i) : i++;
 }
 return oldSize - _size;
 }*/

//有序向量重复元素剔除算法(高效版)
template <typename T> int Vector<T>::uniquify() {
    Rank i = 0;
    Rank j = 0;
    while (++j < _size) {
        if (_elem[i] != _elem[j]) {
            _elem[++i] = _elem[j];
        }
    }
    
    _size = ++i;
    shrink();
    return j - i;
}

//二分查找算法(版本A)
template <typename T> static Rank binSearch(T *A,T const& e,Rank lo,Rank hi){
    while (lo < hi) {
        Rank mi = (lo + hi) >> 1;
        if (e < A[mi]) {
            hi = mi;
        }else if (A[mi] < e) {
            lo = mi + 1;
        }else{
            return mi;
        }
    }//成功查找可以提前终止
    
    return -1;  //查找失败
}

//二分查找算法(版本B)
template <typename T> static Rank binSearchB(T *A,T const& e,Rank lo,Rank hi){
    while (1 < hi- lo) {
        Rank mi = (lo + hi) >> 1;
        (e < A[mi]) ? hi = mi : lo = mi;
    }
    return ( e == A[lo]) ? lo : -1; //查找成功时返回对应的秩,否则统一返回-1
}

//二分查找算法(版本C)
template <typename T> static Rank binSearchC(T *A,T const& e,Rank lo,Rank hi){
    while (lo < hi) {
        Rank mi = (lo + hi) >> 1;
        (e < A[mi]) ? hi = mi : lo = mi+1;
    }
    return --lo;
}//有多个命中元素时,总能保证返回秩最大者;查找失败时,能够返回失败的位置

//fabnacci查找算法
template <typename T> static Rank fibSearch(T *A,T const& e,Rank lo,Rank hi){
    Fib fib(hi-lo);
    
    while (lo < hi) {
        while ( hi - lo > fib.get()) {
            fib.prev();
        }
        
        Rank mi = lo + fib.get() - 1;
        if (e < A[mi]) {
            hi = mi;
        }else if(A[mi] < e) {
            lo = mi + 1;
        }else{
            return mi;
        }
    }
    
    return -1;
}


//在有序向量的区间[lo,hi)内,确定不大于e的最后一个节点的秩
template <typename T> Rank Vector<T>::search(T const& e, Rank lo, Rank hi) const {
    return (rand() % 2) ? binSearch(_elem, e, lo, hi) : fibSearch(_elem, e, lo, hi);
}


//冒泡排序
//一趟扫描交换
template <typename T> bool Vector<T>::bubble(Rank lo, Rank hi) {
    bool sorted = true;
    while (++lo < hi) {
        if (_elem[lo-1] > _elem[lo]) {
            sorted = false;
            std::swap(_elem[lo-1], _elem[lo]);
        }
    }
    
    return sorted;
}

template <typename T> void Vector<T>::bubbleSort(Rank lo, Rank hi){
    while (!bubble(lo, hi--)); //逐趟做扫描交换,直至全序
}

//选择排序
template <typename T>
void Vector<T>::selectionSort(Rank lo,Rank hi) {
    while (lo < --hi) {
        std::swap(_elem[max(lo, hi)], _elem[hi]);
    }
}

template <typename T>
Rank Vector<T>::max(Rank lo, Rank hi) {
    Rank mx = hi;
    while (lo < hi--) {
        if (_elem[hi] > _elem[mx]) {
            mx = hi;
        }
    }
    return mx;
}

//归并排序
template <typename T> void Vector<T>::mergeSort(Rank lo, Rank hi) {
    if (hi - lo < 2) {
        return;
    }
    
    int mi = ( lo + hi) / 2;
    mergeSort(lo, mi);
    mergeSort(mi, hi);
    merge(lo, mi, hi);  //归并
}

template <typename T> void Vector<T>::merge(Rank lo, Rank mi, Rank hi) {
    T *A = _elem + lo;
    int lb = mi - lo;
    T *B = new T[lb];
    
    for (Rank i = 0; i < lb; B[i] = A[i++]);  //复制前子向量
    
    int lc = hi - mi;
    T *C = _elem + mi;
    
    for (Rank i = 0,j = 0,k = 0; (j < lb) || (k < lc) ; ) {
        // !(k < lc)表示C数组合并完了,B数组还没合并完
        if ( (j < lb) && ( !(k < lc) || (B[j] <= C[k] ) )) {
            A[i++] = B[j++];
        }
        if ( (k < lc) && ( !(j < lb) || (C[k] < B[j]))) {
            A[i++] = C[k++];
        }
    }
    
    delete [] B; //释放临时空间
}

//堆排序

//快速排序
template <typename T> void Vector<T>::quickSort(Rank lo, Rank hi) {
    if (hi - lo < 2) {
        return;
    }
    
    Rank mi = partition(lo, hi-1); //在[lo,hi-1]内构造轴点
    quickSort(lo, mi);
    quickSort(mi+1, hi);
}

/*
 //轴点构造算法
 template <typename T>
 Rank Vector<T>::partition(Rank lo, Rank hi) { //版本A:基本形式
 std::swap(_elem[lo], _elem[lo+rand() % (hi-lo+1)]); //任选一个元素与首元素交换
 T pivot = _elem[lo]; //以首元素为候选轴点-----一经以上交换,等效于随机选取
 
 while (lo < hi) {
 while ( (lo < hi) && (pivot <= _elem[hi]) ) {
 hi--;
 }
 
 _elem[lo] = _elem[hi];
 
 while ( (lo < hi) && (this->_elem[lo] <= pivot) ) {
 lo++;
 }
 
 _elem[hi] = _elem[lo];
 }
 
 _elem[lo] = pivot;
 return lo;
 }
 */

//轴点构造算法:通过调整元素位置构造区间[lo,hi]的轴点,并返回其秩
template <typename T>
Rank Vector<T>::partition(Rank lo, Rank hi) { //版本B:可优化处理多个关键码雷同的退化情况
    std::swap(_elem[lo], _elem[lo+rand()%(hi-lo+1)]);
    T pivot = _elem[lo];
    
    while (lo < hi) {
        while (lo < hi) {
            if (pivot < _elem[hi]) {
                hi--;
            }else{
                _elem[lo++] = _elem[hi];
                break;
            }
        }
        
        while (lo < hi) {
            if (_elem[lo] < pivot) {
                lo++;
            }else{
                _elem[hi--] = _elem[lo];
                break;
            }
        }
    }
    
    _elem[lo] = pivot;
    return lo;
}


template <typename T> void Vector<T>::sort(Rank lo, Rank hi) {
    switch (rand() % 5) {
        case 1: bubbleSort(lo, hi); break;     //冒泡排序
        case 2: selectionSort(lo, hi); break;  //选择排序
        case 3: mergeSort(lo, hi); break;      //归并排序
        case 4: heapSort(lo, hi); break;       //堆排序
        default: quickSort(lo, hi); break;     //快速排序
    }
}

 

posted on 2018-11-11 21:34  迷心迷  阅读(296)  评论(0编辑  收藏  举报