2. 一个数组中实现两个栈

  • 《算法导论》10.1-2 如何在一个数组[1...n]中实现两个栈,使得当两个栈的元素个数之和不为n时,两者都不会发生上溢。要求push和pop操作的运行时间为O(1)。
#include <iostream>
template<typename Object>
class DoubleStack
{
public:
    DoubleStack(){init();}
    DoubleStack(const DoubleStack& rhs)
    {
        init();
        top1 = rhs.top1;
        top2 = rhs.top2;
        int i, idx;
        for(i = 0; i != top1 + 1; ++i)
        {
            idx = index1(i);
            p[idx] = rhs.p[idx];
        }
        for(i = 0; i != top2 + 1; ++i)
        {
            idx = index2(i);
            p[idx] = rhs.p[idx];
        }
    }
    DoubleStack(DoubleStack&& rhs):p(rhs.p),top1(rhs.top1),top2(rhs.top2)
    {
        rhs.p = nullptr;
        rhs.top1 = -1;
        rhs.top2 = -1;
    }
    DoubleStack& operator =(const DoubleStack& rhs)
    {
        DoubleStack copy(rhs);
        std::swap(copy.p, this->p);
        std::swap(copy.top1, this->top1);
        std::swap(copy.top2, this->top2);
        return *this;
    }
    DoubleStack& operator =(DoubleStack&& rhs)
    {
        std::swap(rhs.p, this->p);
        std::swap(rhs.top1, this->top1);
        std::swap(rhs.top2, this->top2);
        return *this;
    }
    ~DoubleStack()
    {
        if(p)
            delete[] p;
    }

    void push1(const Object& object)
    {
        if(full())
            std::cout << "overflow" << std::endl;
        else
            p[index1(++top1)] = object;
    }
    void push1(Object&& object)
    {
        if(full())
            std::cout << "overflow" << std::endl;
        else
            p[index1(++top1)] = std::move(object);
    }

    void push2(const Object& object)
    {
        if(full())
            std::cout << "overflow" << std::endl;
        else
            p[index2(++top2)] = object;
    }
    void push2(Object&& object)
    {
        if(full())
            std::cout << "overflow" << std::endl;
        else
            p[index2(++top2)] = std::move(object);
    }

    Object top_1() const
    {
        return p[index1(top1)];
    }

    Object top_2() const
    {
        return p[index2(top2)];
    }

    void    pop1()
    {
        if(empty1())
            std::cout << "underflow" << std::endl;
        else
            --top1;
    }

    void    pop2()
    {
        if(empty2())
            std::cout << "underflow" << std::endl;
        else
            --top2;
    }

    bool    empty1() const{return top1 == -1;}
    bool    empty2() const{return top2 == -1;}
    bool    full() const{return top1 + top2 + 2 == MAX_SIZE;}

private:
    static constexpr int MAX_SIZE = 4;
    Object* p;
    int     top1;
    int     top2;

    void init()
    {
        p = new Object[MAX_SIZE];
        top1 = top2 = -1;
    }

    inline int index1(int top) const
    {
        return top;
    }
    inline int index2(int top) const
    {
        return MAX_SIZE -1 -top;
    }
};

void testDoubleStack()
{
    using namespace std;
    struct Student
    {
        char name[10];
        int  age;
    };
    DoubleStack<Student> ds;
    ds.push1(Student{"Tom", 12});
    ds.push1(Student{"Micheal", 13});
    ds.push1(Student{"Anna", 14});
    ds.push1(Student{"Lily", 10});
    ds.push1(Student{"James", 19});
    while(!ds.empty1())
    {
        auto stu = ds.top_1();
        ds.pop1();
        ds.push2(stu);
    }
    decltype(ds) ds_copy(ds);
    decltype(ds) ds_move(std::move(ds));

    while(!ds_copy.empty2())
    {
        Student stu = ds_copy.top_2();
        cout << "name: " << stu.name << " age: " << stu.age << endl;
        ds_copy.pop2();
    }

    while(!ds_move.empty2())
    {
        Student stu = ds_move.top_2();
        cout << "name: " << stu.name << " age: " << stu.age << endl;
        ds_move.pop2();
    }
/*output:
overflow
name: Tom age: 12
name: Micheal age: 13
name: Anna age: 14
name: Lily age: 10
name: Tom age: 12
name: Micheal age: 13
name: Anna age: 14
name: Lily age: 10
*/
}
posted @ 2018-12-24 16:34  一只美丽的呱呱  阅读(417)  评论(0编辑  收藏  举报