使用两个队列实现一个栈,使用两个栈实现一个队列

一、栈与队列的特点
(一)栈
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。
进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。不含任何元素的栈称为空
栈,栈又称为后进先出的线性表。
栈的特点:后进先出(LIFO)
(二)队列
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作
的特殊线性表。进行插入操作的一端称为队尾,通常称为入队列;进行删除操作的一端称为队头,通常称为出队列。
队列的特点:先进先出(FIFO)
二、用两个栈实现一个队列
使用两个队列实现一个栈,使用两个栈实现一个队列_第1张图片
利用栈与队列的特殊特性,在实现栈与队列的转换之时,只需改变元素的出队列顺序即可
例如有两个栈s1与s2
(1)元素入队列:将入栈元素放在s1中,只是利用s1作为元素的入栈
(2)元素出队列:在栈中,元素先进后出,而在队列中,元素先进先出,因此再出队列之时,借助s2,将栈中的元素进行反置,如果栈s2中有元素,则将s2的栈顶元素删除,如果s2为空栈,则将s1中的元素依次压入到s2中,
直到s1为空,最后在将s2中的栈顶元素弹出即可
(3)取队列的头元素:如果s2不为空,则取s2的栈顶元素,如果s2为空,则将s1中的元素依次压入到s2中,再取s2的栈顶元素即可
(4)取队尾元素:如果s1不为空,取s1的栈顶元素即可,如果s1为空而s2不为空,则将s2中的元素压入到s1中,再取s1的栈顶元素即可
(5)求队列中元素的总个数:即s1中元素的总个数+s2中元素的总个数
(6)判断队列是否为空:如果s1与s2都为空,则队列就为空

主要代码如下所示:

//用两个栈实现一个队列
template<class T>
class Queue
{
public:
    Queue()
    {}

    void Push(const T&data)
    {
        s1.push(data);
    }

    void Pop()
    {
        if (!s2.empty())
        {
            s2.pop();
            return;
        }

        while (!s1.empty())
        {
            while (s1.size() != 0)
            {
                s2.push(s1.top());
                s1.pop();
            }
            s2.pop();
        }
    }

    T Front()
    {
        if (!s2.empty())
        {
            return s2.top();
        }
        while (!s1.empty())
        {
            s2.push(s1.top());
            s1.pop();
        }
        return s2.top();
    }
    T Back()
    {
        if (!s1.empty())
        {
            return s1.top();
        }
        while (!s2.empty())
        {
            s1.push(s2.top());
            s2.pop();
        }
        return s1.top();
    }

    size_t Size()
    {
        return s1.size() + s2.size();
    }

    bool Empty()
    {
        if (s1.empty() && s2.empty())
            return true;
        else
            return false;
    }
private:
    stack s1;
    stack s2;
};

测试代码如下所示:

用两个栈实现一个队列
void TestLineStack()
{
    //用两个栈实现一个队列
    Queue<int> s;
    //孔队列
    s.Pop();
    if (s.Empty())
    {
        cout << "空" << endl;
        cout << "Size=" << s.Size() << endl;
    }
    else
    {
        cout << "非空" << endl;
        cout << "Front=" << s.Front() << endl;
        cout << "Back=" << s.Back() << endl;
        cout << "Size=" << s.Size() << endl;
    }
    //队列中有元素
    s.Push(1);
    s.Push(2);
    s.Push(3);
    if (s.Empty())
    {
        cout << "空" << endl;
        cout << "Size=" << s.Size() << endl;
    }
    else
    {
        cout << "非空" << endl;
        cout << "Front=" << s.Front() << endl;
        cout << "Back=" << s.Back() << endl;
        cout << "Size=" << s.Size() << endl;
    }
    //从对列中删除元素
    s.Pop();
    if (s.Empty())
    {
        cout << "空" << endl;
        cout << "Size=" << s.Size() << endl;
    }
    else
    {
        cout << "非空" << endl;
        cout << "Front=" << s.Front() << endl;
        cout << "Back=" << s.Back() << endl;
        cout << "Size=" << s.Size() << endl;
    }
    //添加元素
    s.Push(4);
    if (s.Empty())
    {
        cout << "空" << endl;
        cout << "Size=" << s.Size() << endl;
    }
    else
    {
        cout << "非空" << endl;
        cout << "Front=" << s.Front() << endl;
        cout << "Back=" << s.Back() << endl;
        cout << "Size=" << s.Size() << endl;
    }

    //删除队列中的元素直到为空

    s.Pop();
    s.Pop();
    s.Pop();
    if (s.Empty())
    {
        cout << "空" << endl;
        cout << "Size=" << s.Size() << endl;
    }
    else
    {
        cout << "非空" << endl;
        cout << "Front=" << s.Front() << endl;
        cout << "Back=" << s.Back() << endl;
        cout << "Size=" << s.Size() << endl;
    }
}

结果如下所示:
使用两个队列实现一个栈,使用两个栈实现一个队列_第2张图片

三、利用两个队列实现一个栈
利用两个队列实现一个栈中,将一个队列作为使用队列,一个队列作为空置队列,即利用两个标记值,判断队列的使用情况
例如有两个队列q1,q1_used,q2,q2_used,初始值设为q1_used=true,q2_used=false,因此在最初之时,默认将元素放在q1中
(1)元素入栈:将所有元素放在使用的队列中
(2)元素出栈:如果当前q1为使用的队列,将队列q1中的元素按照队列的特性依次放入到q2中,直至队列q1只有一个元素为止,删除q1中的最后一个元素,最后修改q1与q2的使用状态,
如果q2为当前使用的队列,情况与上面相同。
(3)取栈顶元素:即取非空队列中的队尾元素
(4)求栈中元素个数的多少:即取非空队列中元素的个数
(5)判断栈是否为空:如果q1与q2都为空,则栈就为空

主代码如下所示:

//用两个队列实现一个栈
template<class T>
class Stack
{
public:
    Stack()     
    {
        q1_used = true;//作为入队列
        q2_used = false;
    }
    void Push(const T&data)
    {
        if (q1_used == true)
        {
            q1.push(data);
            return;
        }
        if (q2_used == true)
        {
            q2.push(data);
            return;
        }

    }

    void Pop()
    {
        if (!q1.empty())
        {
            while (q1.front() != q1.back())
            {
                q2.push(q1.front());
                q1.pop();
            }
            q1.pop();
            q1_used = false;
            q2_used = true;
            return;
        }
        if (!q2.empty())
        {
            while (q2.front() != q2.back())
            {
                q1.push(q2.front());
                q2.pop();
            }
            q2.pop();
            q1_used = true;
            q2_used = false;
            return;
        }
        return;
    }

    T Top()
    {
        if (!q1.empty())
            return q1.back();
        if (!q2.empty())
            return q2.back();
        return NULL;
    }
    size_t Size()
    {
        if (!q1.empty())
        {
            return q1.size();
        }
        if (!q2.empty())
        {
            return q2.size();
        }
        return 0;
    }
    bool Empty()
    {
        if (q1.empty() && q2.empty())
            return true;
        else
            false;
    }
private:
    queue q1;
    bool q1_used;
    queue q2;
    bool q2_used;
};

测试代码如下所示:

//用两个队列实现一个栈
void TestStackLine()
{
    Stack<int> s;
    //空栈
    s.Pop();
    if (s.Empty())
    {
        cout << "空" << endl;
        cout << "Size=" << s.Size() << endl;
    }
    else
    {
        cout << "非空" << endl;
        cout <<"Top="<< s.Top() << endl;
        cout << "Size=" << s.Size() << endl;
    }
    //往栈中添加元素
    s.Push(1);
    s.Push(2);
    s.Push(3);
    s.Push(4);
    s.Push(5);
    s.Push(7);
    if (s.Empty())
    {
        cout << "空" << endl;
        cout << "Size=" << s.Size() << endl;
    }
    else
    {
        cout << "非空" << endl;
        cout << "Top=" << s.Top() << endl;
        cout << "Size=" << s.Size() << endl;
    }
    //删除栈中元素
    s.Pop();
    //s.Pop();
    if (s.Empty())
    {
        cout << "空" << endl;
        cout << "Size=" << s.Size() << endl;
    }
    else
    {
        cout << "非空" << endl;
        cout << "Top=" << s.Top() << endl;
        cout << "Size=" << s.Size() << endl;
    }
    //删除栈中元素直至为空
    s.Pop();
    s.Pop();
    s.Pop();
    s.Pop();
    s.Pop();
    s.Pop();
    if (s.Empty())
    {
        cout << "空" << endl;
        cout << "Size=" << s.Size() << endl;
    }
    else
    {
        cout << "非空" << endl;
        cout << "Top=" << s.Top() << endl;
        cout << "Size=" << s.Size() << endl;
    }
}

结果如下所示:
使用两个队列实现一个栈,使用两个栈实现一个队列_第3张图片

只有不停的奔跑,才能不停留在原地!!!

你可能感兴趣的:(c++,数据结构)