vector模板类的C++实现

vector的实现 vector.h
/*
2017/07/19
Liu YK
*/

#pragma once
#include <cassert>
#include <iostream>
#include <cstdlib>
#include <ctime>

namespace MYSTL
{
    typedef int Rank;
    const int DEFAULT_CAPACITY = 5;

    template<typename T>
    class  vector
    {
    public:
        friend std::ostream& operator<< (std::ostream& os, const vector<T> &v)
        {
            for (Rank i = 0; i < v.m_size; ++i)
                os << v.m_data[i] << " ";
            return os;
        }

    public:
        //构造函数和析构函数
        vector(int cap = DEFAULT_CAPACITY, int sz = 0, const T v = T());
        vector(const T *arr, int n) { copyFrom(arr, 0, n); }
        vector(const T *arr, Rank lo, Rank hi) { copyFrom(arr, lo, hi); }
        vector(const vector<T> &v) { copyFrom(v.m_data, 0, v.m_size); }
        vector(const vector<T> &v, Rank lo, Rank hi) { copyFrom(v.m_data, lo, hi); }
        ~vector() { delete [] m_data; }
        vector<T>& operator = (const vector<T> &v);

        //只读接口
        int capacity() const { return m_capacity; }
        int size() const { return m_size; }
        bool empty() const { return !m_size; }
        Rank find(const T &e) const;
        Rank find(const T &e, Rank lo, Rank hi) const;
        Rank search(const T &e) const;
        Rank search(const T &e, Rank lo, Rank hi) const;
        int disordered() const;
        //void print() const;


        //可写访问接口
        void push_back(const T &e) { insert(e); }
        void pop_back() { remove(m_size - 1); }
        T& operator[](Rank r) { assert(r >= 0 && r < m_size); return m_data[r]; }
        Rank insert(Rank r, const T &e);
        Rank insert(const T &e);
        const T remove(Rank r);
        int remove(Rank lo, Rank hi);
        void clear();
        int deduplicate();
        int uniquify();
        void sort(Rank lo, Rank hi);
        void sort();
    protected:
        void copyFrom(const T *data, Rank lo, Rank hi);
        void expand();
        void shrink();
        void bubbleSort(Rank lo, Rank hi);
        void selectSort(Rank lo, Rank hi);
        void insertSort(Rank lo, Rank hi);
        void mergeSort(Rank lo, Rank hi);
        void merge(Rank lo, Rank mid, Rank hi);
        Rank binSearch(const T &e, Rank lo, Rank hi) const;
        Rank binSearch_impl1(const T &e, Rank lo, Rank hi) const;//失败返回-1
        Rank binSearch_impl2(const T &e, Rank lo, Rank hi) const;//失败返回-1
        Rank binSearch_impl3(const T &e, Rank lo, Rank hi) const;//失败返回不大于e的最大秩

    private:
        int uniquify_impl1();
        int uniquify_impl2();
        static void swap(T &a, T &b) { T tmp = a; a = b; b = tmp; }

    protected:
        Rank m_capacity;
        Rank m_size;
        T *m_data;

    };

    template<typename T>
    vector<T>::vector(int cap = DEFAULT_CAPACITY, int sz = 0, T v = T())
        : m_capacity(cap), m_size(sz)
    {
        m_data = new T[m_capacity];
        for (int i = 0; i < m_size; ++i)
            m_data[i] = v;
    }

    template<typename T>
    inline vector<T>& vector<T>::operator=(const vector<T>& v)
    {
        if (m_data == v.m_data)
            return *this;
        delete[] m_data;
        copyFrom(v.m_data, 0, v.m_size);

        return *this;
    }

    template<typename T>
    inline Rank vector<T>::find(const T & e) const
    {
        return find(e, 0, m_size);
    }

    template<typename T>
    inline Rank vector<T>::find(const T & e, Rank lo, Rank hi) const
    {
        assert(lo >= 0 && hi <= m_size && lo < hi);
        while (--hi >= lo)
        {
            if (e == m_data[hi])
                return hi;
        }

        return -1;
    }

    template<typename T>
    inline Rank vector<T>::search(const T & e) const
    {
        return search(e, 0, m_size);
    }

    template<typename T>
    inline Rank vector<T>::search(const T & e, Rank lo, Rank hi) const
    {
        return binSearch(e, lo, hi);
    }

    template<typename T>
    inline int vector<T>::disordered() const
    {
        int ret = 0;
        for (int i = 1; i < m_size; ++i)
        {
            if (m_data[i - 1] > m_data[i])
                ++ret;
        }

        return ret;
    }

    /*template<typename T>
    inline void vector<T>::print() const
    {
        for (Rank i = 0; i < m_size; ++i)
            std::cout << m_data[i] << " ";
        std::cout << std::endl;
    }*/

    template<typename T>
    inline Rank vector<T>::insert(Rank r, const T & e)
    {
        assert(r >= 0 && r <= m_size);

        expand();
        for (Rank i = m_size; i > r; --i)
        {
            m_data[i] = m_data[i - 1];
        }
        m_data[r] = e;
        ++m_size;

        return r;
    }

    template<typename T>
    inline Rank vector<T>::insert(const T & e)
    {
        return insert(m_size, e);
    }

    template<typename T>
    inline const T vector<T>::remove(Rank r)
    {
        assert(r >= 0 && r < m_size);

        T ret = m_data[r];
        remove(r, r + 1);

        return ret;
    }

    template<typename T>
    inline int vector<T>::remove(Rank lo, Rank hi)
    {
        assert(lo >= 0 && hi <= m_size && lo < hi);

        int ret = hi - lo;
        for (Rank i = hi; i < m_size; ++i)
        {
            m_data[lo++] = m_data[i];
        }

        m_size -= ret;
        shrink();

        return ret;
    }

    template<typename T>
    inline void vector<T>::clear()
    {
        remove(0, m_size);
    }

    template<typename T>
    inline int vector<T>::deduplicate()
    {
        int old_size = m_size;
        for (int i = 1; i < size();)
        {
            if (find(m_data[i], 0, i) != -1)
                remove(i);
            else
                ++i;
        }
        return old_size - m_size;
    }

    template<typename T>
    inline int vector<T>::uniquify()
    {
        return uniquify_impl2();
    }

    template<typename T>
    inline void vector<T>::sort(Rank lo, Rank hi)
    {
        srand(static_cast<unsigned int> (time(nullptr)));

        switch (rand() % 5)
        {
        case 0 : 
            bubbleSort(lo, hi);
            break;
        case 1 :
            selectSort(lo, hi);
            break;
        case 2 : 
            insertSort(lo, hi);
            break;
        case 3 :
        default:
            mergeSort(lo, hi);
            break;
        }
    }

    template<typename T>
    inline void vector<T>::sort()
    {
        sort(0, m_size);
    }

    template<typename T>
    inline void vector<T>::expand()
    {
        if (m_size == m_capacity)
        {
            T *old_data = m_data;
            if (m_capacity < DEFAULT_CAPACITY)
                m_capacity = DEFAULT_CAPACITY;
            m_data = new T[m_capacity <<= 1];
            copyFrom(old_data, 0, m_size);
            delete[] old_data;
        }
    }

    template<typename T>
    inline void vector<T>::shrink()
    {
        if (m_size * 5 < m_capacity)
        {
            T *old_data = m_data;
            m_capacity = (m_capacity / 2 < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : (m_capacity >> 1);
            m_data = new T[m_capacity];
            //copyFrom(old_data, 0, m_size);
            for (int i = 0; i < m_size; ++i)
                m_data[i] = old_data[i];
            delete[] old_data;
        }
    }

    template<typename T>
    inline void vector<T>::bubbleSort(Rank lo, Rank hi)
    {
        assert(lo >= 0 && hi <= m_size && lo < hi);

        bool sorted = false;
        while (!sorted)
        {
            sorted = true;
            for (Rank i = lo + 1; i < hi; ++i)
            {
                if (m_data[i - 1] > m_data[i])
                {
                    swap(m_data[i - 1], m_data[i]);
                    sorted = false;
                }
            }

            --hi;
        }
    }

    template<typename T>
    inline void vector<T>::selectSort(Rank lo, Rank hi)
    {
        assert(lo >= 0 && hi <= m_size);
        for (int i = 0; i < m_size; ++i)
        {
            T min = m_data[i];
            Rank min_idx = i;
            for (int j = i + 1; j < m_size; ++j)
            {
                if (m_data[j] < min)
                {
                    min = m_data[j];
                    min_idx = j;
                }

            }
            swap(m_data[min_idx], m_data[i]);
        }
    }

    template<typename T>
    inline void vector<T>::insertSort(Rank lo, Rank hi)
    {
        assert(lo >= 0 && hi <= m_size);

        for (Rank i = lo + 1; i < hi; ++i)
        {
            for (Rank j = i; j > lo; --j)
            {
                if (m_data[j] < m_data[j - 1])
                    swap(m_data[j], m_data[j - 1]);
                else
                    break;
            }
        }
    }

    template<typename T>
    inline void vector<T>::mergeSort(Rank lo, Rank hi)
    {
        assert(lo >= 0 && hi <= m_size);
        if (1 < (hi - lo))
        {
            Rank mid = (hi + lo) >> 1;
            mergeSort(lo, mid);
            mergeSort(mid, hi);
            merge(lo, mid, hi);
        }
    }

    template<typename T>
    inline void vector<T>::merge(Rank lo, Rank mid, Rank hi)
    {
        assert(lo >= 0 && hi <= m_size && lo < mid && mid < hi);

        T *A = m_data + lo;
        Rank lb = mid - lo;
        T *B = new T[lb];
        T *C = m_data + mid;
        Rank lc = hi - mid;

        for (Rank i = 0; i < lb; ++i)
            B[i] = A[i];

        Rank i = 0;
        Rank j = 0;
        Rank k = 0;
        while ((j < lb) && (k < lc))
        {
            if (B[j] < C[k])
                A[i++] = B[j++];
            else
                A[i++] = C[k++];
        }

        if (j >= lb)
        {
            while (k < lc)
                A[i++] = C[k++];
        }
        if (k >= lc)
        {
            while (j < lb)
                A[i++] = C[j++];
        }

        delete[] B;
    }

    template<typename T>
    inline Rank vector<T>::binSearch(const T &e, Rank lo, Rank hi) const
    {
        srand(static_cast<unsigned int> (time(nullptr)));
        switch (2)
        {
        case 0 : 
            return binSearch_impl1(e, lo, hi);
        case 1:
            return binSearch_impl2(e, lo, hi);
        case 2:
        default:
            return binSearch_impl3(e, lo, hi);
        }
    }

    template<typename T>
    inline Rank vector<T>::binSearch_impl1(const T & e, Rank lo, Rank hi) const
    {
        assert(lo >= 0 && hi <= m_size);

        while (lo < hi)
        {
            Rank mid = (lo + hi) >> 1;
            if (e == m_data[mid])
                return mid;
            else if (e < m_data[mid])
                hi = mid;
            else
                lo = mid + 1;
        }

        return -1;
    }

    template<typename T>
    inline Rank vector<T>::binSearch_impl2(const T & e, Rank lo, Rank hi) const
    {
        assert(lo >= 0 && hi <= m_size);

        while (1 < (hi - lo))
        {
            Rank mid = (hi + lo) >> 1;
            if (e < m_data[mid])
                hi = mid;
            else
                lo = mid;
        }

        return (e == m_data[lo]) ? lo : -1;
    }

    template<typename T>
    inline Rank vector<T>::binSearch_impl3(const T & e, Rank lo, Rank hi) const
    {
        assert(lo >= 0 && hi <= m_size);

        while (lo < hi)
        {
            Rank mid = (lo + hi) >> 1;
            (e < m_data[mid]) ? hi = mid : lo = mid + 1;
        }

        return --lo;
    }

    template<typename T>
    inline int vector<T>::uniquify_impl1()
    {
        int ret = 0;
        for (Rank i = 0; i < m_size;)
        {
            Rank j = i + 1;
            while (j < m_size)
            {
                if (m_data[i] == m_data[j])
                    ++j;
                break;
            }
            if (i + 1 != j)
            {
                ret += remove(i + 1, j);
                i = j;
            }
            else
                ++i;
        }

        shrink();
        return ret;
    }

    template<typename T>
    inline int vector<T>::uniquify_impl2()
    {
        Rank i = 0;
        Rank j = 0;
        while (++j < m_size)
        {
            if (m_data[i] != m_data[j])
                m_data[++i] = m_data[j];
        }
        m_size = ++i;
        shrink();

        return j - i;
    }



    template<typename T>
    void vector<T>::copyFrom(const T *data, Rank lo, Rank hi)
    {
        //m_capacity = ((hi - lo) > DEFAULT_CAPACITY / 2) ? ((hi - lo) << 1) : DEFAULT_CAPACITY;
        m_data = new T[m_capacity = (hi - lo) << 1];
        m_size = 0;
        while (lo < hi)
        {
            m_data[m_size++] = data[lo++];
        }
    }
}
测试程序
void test_vector()
{
    //测试构造函数
    int a[] = { 23, 2, 12, 44, -21, 44 };
    int sz = sizeof(a) / sizeof(int);
    MYSTL::vector<int> iv(a, sz);
    cout << iv << endl;
    cout << "The capacity is " << iv.capacity() << endl;
    cout << "The size is " << iv.size() << endl;
    MYSTL::vector<int> iv1(iv);
    cout << iv << endl;
    MYSTL::vector<int> iv11(iv, 0, iv.size() / 2);
    cout << iv11 << endl;
    MYSTL::vector<int> iv111(a, 0, sz / 2);
    cout << iv111 << endl;
    cout << "-------------------------------------------" << endl;

    //测试capacity() size() find() 默认构造函数
    MYSTL::vector<string> sv(10, 5, "hello");
    cout << "The capacity is " << sv.capacity() << endl;
    cout << "The size is " << sv.size() << endl;
    for (int i = 0; i < sv.size(); ++i)
        cout << "iv[" << i << "] = " << sv[i] << endl;
    sv.deduplicate();
    cout << "After deduplicate:" << endl;
    cout << sv << endl;

    MYSTL::vector<int> iv2;
    cout << "The capacity is " << iv2.capacity() << endl;
    cout << "The size is " << iv2.size() << endl;
    if (iv2.empty())
        cout << "iv2 is empty" << endl;
    cout << "---------------------------------------" << endl;
    //测试写访问操作
    for (int i = 0; i < 20; ++i)
        iv2.insert(i);
    cout << "12 is in Rank " << iv2.find(12) << endl;
    cout << iv2 << endl;
    cout << "After insert: " << endl;
    cout << "The capacity is " << iv2.capacity() << endl;
    cout << "The size is " << iv2.size() << endl;

    iv2.insert(10, 100);
    cout << "After insert: " << endl;
    cout << iv2 << endl;
    cout << "After expand: " << endl;
    cout << "The capacity is " << iv2.capacity() << endl;
    cout << "The size is " << iv2.size() << endl;

    iv2.remove(0);
    cout << "After remove Rank 0:" << endl;
    cout << iv2 << endl;
    cout << "The size is " <<  iv2.size() << endl;

    iv2.remove(3, iv2.size());
    cout << "After remove between Rank 3 to end:" << endl;
    cout << iv2 << endl;
    cout << "The capacity is " << iv2.capacity() << endl;
    cout << "The size is " << iv2.size() << endl;
    iv2 = iv;
    cout << "After assign, iv2 is:" << endl;
    cout << iv2 << endl;
    cout << "The capacity is " << iv2.capacity() << endl;
    cout << "The size is " << iv2.size() << endl;

    MYSTL::vector<int> iv3;
    cout << "The capacity is " << iv3.capacity() << endl;
    cout << "The size is " << iv3.size() << endl;
    for (int i = 0; i < 100; ++i)
        iv3.push_back(i);
    cout << "iv3 is " << endl;
    cout << iv3 << endl;
    cout << "The capacity is " << iv3.capacity() << endl;
    cout << "The size is " << iv3.size() << endl;

    for (int i = 0; i < 100; ++i)
        iv3.pop_back();
    cout << "iv3 is " << endl;
    cout << iv3 << endl;
    cout << "The capacity is " << iv3.capacity() << endl;
    cout << "The size is " << iv3.size() << endl;

    //测试有序向量
    int a1[] = { 23, 32, 23, 1, 21, -3, 2, 23, -3, 1, 23 };
    int sz1 = sizeof(a1) / sizeof(int);
    MYSTL::vector<int> iv4(a1, sz1);
    MYSTL::vector<int> iv5(iv4);
    cout << "Before sort:" << endl;
    cout << iv4 << endl;
    cout << "reverse pair is " << iv4.disordered() << endl;
    iv4.sort();
    cout << "After sort:" << endl;
    cout << iv4 << endl;
    cout << "reverse pair is " << iv4.disordered() << endl;

    cout << "iv5 is " << endl;
    cout << iv5 << endl;
    iv5.deduplicate();
    cout << "After deduplicate" << endl;
    cout << iv5 << endl;

    iv5.sort();
    iv5.uniquify();
    cout << "After uniquify" << endl;
    cout << iv5 << endl;
    cout << iv5.search(20) << endl;
    //测试clear
    iv5.clear();
    cout << "Is empty? " << iv5.empty() << endl;
 }
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值