数据结构 第三章 向量源码

这篇博客详细介绍了C++中使用模板实现的向量类,包括了动态扩容、收缩内存、排序算法(如冒泡、选择、归并、堆排序、快速排序)以及查找算法(如二分查找、斐波那契查找)。此外,还提供了元素插入、删除、去重等操作,并讨论了向量的无序化和遍历功能。
摘要由CSDN通过智能技术生成
#include<iostream>
#include<vector>
using namespace std;

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 );
        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 lo, Rank hi){ copyFrom(A,lo,hi);}
        Vector(T const* A, Rank n){ copyFrom(A, 0, n);}
        Vector(Vector<T> const& v, Rank lo, Rank hi){ copyFrom(V._elem,0,V._size);}
        Vector(Vector<T> const& v){ copyFrom(V._elem,0,V._size);}

        ~Vector(){ delete [] _elem;}

        Rank size() const{return _size;}
        bool empty() const{return !_size;}
        int disordered() const;
        Rank find(T const& e)const {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 lo, T const& e);
        Rank insert(T const& e){ return insert(_size,e);}
        void unsort(Rank lo, Rank hi);
        void unsort(){ unsort(0,_size);}
        int depulicate();
        int uniquify();

        void traverse(void (*)(T&));
        template <typename VST> void traverse(VST&);
};

//代码2.2 基于复制的向量构造器
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++];
    }

//代码2.3 重载向量赋值操作符
template <typename T> 
Vector<T>& Vector<T>::operator=(Vector<T> const& V)
{
    if(_elem) delete[] _elem;
    copyFrom(V._elem,0,V.size());
    return *this;
}

//代码2.4 向量内部数组动态扩容算法
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];//右移一位,乘以2倍
    for(int i = 0; i < _size; ++i)
        _elem[i] = oldElem[i];
    delete [] oldElem;
}

//代码2.5 向量内部功能shrink()
template <typename T>
void Vector<T>::shrink()
{
    if(_capacity < DEFAULT_CAPACITY << 1)return;
    if(_size << 2 > _capacity)return;
    T* oldElem = _elem;
    _elem = new T[_capacity >>= 1];
    for(int i = 0; i < _size; i++)
        _elem[i] = oldElem[i];
        delete [] oldElem;
}

//代码2.6 重载向量操作符
template <typename T>
T& Vector<T>::operator[](Rank r)const
{
    return _elem[r];
}

//代码2.7 向量整体置乱算法
template <typename T>
void permute(Vector<T>& V)
{
    for(int i = V.size(); i > 0; i--)
        swap(V[i - 1], V[rand() % i]);
}

//代码2.8 向量区间置乱接口
template <typename T>
void Vector<T>::unsort(Rank lo, Rank hi)
{
    T* V = _elem + lo;
    for(Rank i = hi - lo; i > 0; i--)
        swap(V[i - 1], V[rand() % i]);
}

//代码2.9 重载比较器以便比较对象指针
template <typename T> 
static bool lt(T* a, T*b)
{
    return lt(*a, *b);
}
template <typename T>
static bool lt(T& a, T& b)
{
    return a < b;
}
template <typename T>
static bool eq(T* a, T* b)
{
    return eq(*a, *b);
}
template <typename T>
static bool eq(T& a, T& b)
{
    return a == b;
}

//代码2.10 无序向量查找接口 find()
template <typename T>
Rank Vector<T>::find(T const& e, Rank lo, Rank hi)const
{
    while((lo < hi--) && (e != _elem[hi]));
    return hi;
}

//代码2.11 向量元素插入接口insert()
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++;
    return r;
}

//代码2.12 向量区间删除接口remove(lo,hi)
template <typename T>
int Vector<T>::remove(Rank lo, Rank hi)
{
    if(lo == hi)return 0;
    while(hi < _size) 
        _elem[lo++] = _elem[hi++];
    _size = lo;
    shrink();
    return hi - lo;
}

//代码2.13 向量单元删除接口
template<typename T>
T Vector<T>::remove(Rank r)
{
    T e = _elem[r];
    remove(r,r + 1);
    return e;
}

//代码2.14 无序向量清除重复元素接口deduplicate()
template <typename T> 
int Vector<T>::depulicate()
{
    int oldSide = _size;
    Rank i = 1;
    while( i < _size)
        (find(_elem[i],0,i) < 0) ? i++ : remove(i);
    return oldSide - _size;
}

//代码2.15 向量遍历接口traverse()
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]);
}

//代码2.16 基于遍历实现increase()功能
template <typename T> struct Increase
{
    virtual void operator()(T& e)
    {
        e++;
    }
};
template <typename T> void increase(Vector<T> & V)
{
    V.traverse(Increase<T>());
}

//代码2.17 有序向量甄别算法
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;
}

//代码2.18 有序向量uniquify()接口的平凡实现
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;
}

//代码2.19 有序向量uniquify()接口的高效实现
template <typename T>
int Vector<T>::uniquify()
{
    Rank i = 0, j = 0;
    while(++j < _size)
        if(_elem[i] != _elem[j])
            _elem[++i] = _elem[j];
    _size = ++i;
    shrink();
    return j - 1;
}

//代码2.20 有序向量各种查找算法的统一接口search()
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);
}

//代码2.21 二分查找算法
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;
}

//代码2.22 Fibonacci算法
//#include "..\fibonacci\Fib.h"
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;
}

//代码2.23 二分查找算法
template <typename T>
static Rank binSearch(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;
}

//代码2.24 二分查找算法
template <typename T>
static Rank binSearch(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;
}

//代码2.25 向量排序接口
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;
    }
}

//代码2.26 单趟扫描交换
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;
            swap(_elem[lo - 1]._elem[lo]);
        }
    return sorted;
    
}

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

//代码2.29 有序向量的二路归并
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 = mi +_elem;
    for(Rank i = 0, j = 0, k = 0; (j < lb) || (k < lc);)
    {
        if((j < lb) && (!(B[j] <= C[k])))
            A[i++] = B[j++];
        if((k < lc) && (!(C[k] < B[j])))
            A[i++] = C[k++];
    }
    delete [] B;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值