deque的一种简单实现

2018-02-23  本文已影响0人  IT孤独者

STL库中的deque是一种非常有用的数据结构。嗯。。。好吧,我也不经常用这个数据结构!!!

deque的实现需要考虑的两个问题:

如果想实现随机存取,我们必须有计算公式,能够直接根据指定的值算出element所在的位置。
想实现两端push和pop我们必须能够有一种类似链表的结构支持这样的做法。

为了达到上面的目的,我使用的结构是:

map<int, vector<T*>> dq;

map是一种映射表,如果我采用连续的整数做关键字,那么就可以实现两端push和pop,如果我固定vector的大小,那么我就可以使用固定公式计算element的位置。当然,你也可以使用其他的数据结构,这只是我的一种简单实现罢了!!!

在写代码的过程中,我发现我大部分的时间都是在构造计算公式,对于vector的实现而言,deque的计算公式要稍微复杂一点(其实也没有了,就是初中的加减乘除,不过对于我来说,实现的时候还是费脑子的)

代码如下:

template<typename T>
class MyDeque
{
public:
    MyDeque()
    {
        base = 0;
        curbase = 0;
        tail = 0;
        curtail = 0;
    }
    ~MyDeque()
    {
        for (auto itr = dq.begin(); itr != dq.end(); ++itr)
        {
            for (auto itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
            {
                delete *itr2;
                *itr2 = nullptr;
            }
        }

        dq.clear();
    }

    void push_back(const T & ele)
    {
        while (true)
        {
            if (dq.find(tail) == dq.end())
            {
                dq[tail] = vector<T*>(l, nullptr);
                curtail = 0;
            }

            if (curtail >= l)
            {
                tail += 1;
                curtail = 0;
                continue;
            }

            dq[tail][curtail] = new T(ele);
            curtail += 1;

            break;
        }
    }

    void pop_back()
    {
        if (base == tail && curbase == curtail)
        {
            return;
        }

        delete dq[tail][curtail - 1];
        dq[tail][curtail - 1] = nullptr;
        curtail -= 1;

        if (curtail <= 0)
        {
            tail -= 1;
            curtail = l;
        }
    }

    void push_front(const T & ele)
    {
        while (true)
        {
            if (dq.find(base) == dq.end())
            {
                dq[base] = vector<T*>(l, nullptr);
                curbase = l;
            }


            if (curbase <= 0)
            {
                base -= 1;
                curbase = l;
                continue;
            }

            dq[base][curbase - 1] = new T(ele);
            curbase -= 1;

            break;
        }
    }

    void pop_front()
    {
        if (base == tail && curbase == curtail)
        {
            return;
        }

        delete dq[base][curbase];
        dq[base][curbase] = nullptr;
        curbase += 1;

        if (curbase == l)
        {
            base += 1;
            curbase = 0;
        }
    }

    T & operator[](int pos)
    {   
        assert(pos >= 0 && pos < size());

        return pos < (l - curbase) ? *(dq[base][curbase + pos]) :
            *(dq[base + (pos - (l - curbase)) / l + 1][(pos - (l - curbase)) % l]);
    }

    int size()
    {
        return (l - curbase) + curtail + (tail - base + 1 - 2) * l;
    }

private:
    int base;
    int curbase;
    int tail;
    int curtail;
    static const int l = 50000;

    map<int, vector<T*>> dq;
};
上一篇 下一篇

猜你喜欢

热点阅读