数据结构-使用两个栈实现一个队列

1:如何只使用stack实现queue呢?我们知道stack是先进后出的(FIFO),而queue是先进先出的(FIFO)。也就是说,stack进行了一次反向。如果进行两次反向,就能实现queue的功能,所以我们需要两个stack实现queue。

    下面是具体思路。

假设有两个栈A和B,且都为空。可以认为栈A为提供入队列的功能,栈B提供出队列的功能。

(1)如果栈B不为空,直接弹出栈B的数据。

(2)如果栈B为空,则依次弹出栈A的数据,放入到栈B中,再弹出栈B的数据。

代码如下:

#include "stdafx.h"
#include<malloc.h>
#include <iostream>
#include <assert.h>
using namespace std;

/*单链表的节点,data表示节点的数据域,next指向下一个节点*/
class MyData
{
public:
    MyData() :data(0), next(NULL) {};//默认构造函数,这样表示后,主体中不用再写这个函数了
    MyData(int value) :data(value), next(NULL) {};//带参数的构造函数
    int data;//数据域
    MyData *next;//下一个节点
};

/*表示栈的定义,其中public成员top表示栈顶,由于不能直接操作栈底,因此这里没有定义栈底的指针。
在默认构造函数中,把栈顶指针top置空,表示此时栈为空栈。*/
class MyStack
{
public:
    MyStack() :top(NULL) {};//默认构造函数
    void push(MyData data);//进栈
    void pop(MyData *pData);//出栈
    bool IsEmpty();//是否为空栈
    MyData *top;//栈顶
};

class MyQueue
{
public:
    void enqueue(MyData data);//入队
    void dequeue(MyData &data);//出队
    bool IsEmpty();//是否为空队
private:
    MyStack s1;//用于入队
    MyStack s2;//用于出队
};

//进栈
void MyStack::push(MyData data)
{
    MyData *pData = NULL;
    pData = new MyData(data.data);//生成新节点
    pData->next = top;
    top = pData;
}

//判断栈是否为空
bool MyStack::IsEmpty()
{
    return(top == NULL);//如果top为空,则返回1,否则返回0
}

//出栈
void MyStack::pop(MyData *data)//将删除的节点保存到data中
{
    if (IsEmpty())//如果栈为空,直接返回
    {
        return;
    }
    data->data = top->data;//给传出的参数赋值
    MyData *p = top;//临时保存原栈顶节点
    top = top->next;//移动栈顶,指向下一个节点
    delete p;//释放原栈顶节点内存
}


//入队
void MyQueue::enqueue(MyData data)
{
    s1.push(data);//只对s1进行操作
}

//出队
void MyQueue::dequeue(MyData &data)
{
    MyData temp(0);//局部变量,用于临时存储
    if (s2.IsEmpty())
    {
        while (!s1.IsEmpty())//如果s2为空,把s1的所有元素push到s2中
        {
            s1.pop(&temp);//弹出s1的元素
            s2.push(temp);//压入s2中
        }
    }
    if (!s2.IsEmpty())
    {
        s2.pop(&data);//此时s2不为空,则弹出s2的栈顶元素
    }
}

//队列判空
bool MyQueue::IsEmpty()
{
    //如果两个栈都为空,则返回1,否则返回0
    return(s1.IsEmpty() && s2.IsEmpty());
}
int main()
{
    MyData data(0);//定义一个节点
    MyQueue q;

    q.enqueue(MyData(1));
    q.enqueue(MyData(2));
    q.enqueue(MyData(3));

    q.dequeue(data);
    cout << "dequeue" << data.data << endl;
    q.dequeue(data);
    cout << "dequeue" << data.data << endl;
    q.dequeue(data);
    cout << "dequeue" << data.data << endl;
    cout << "IsEmpty:" << q.IsEmpty() << endl;


    return 0;
}
View Code

运行结果:

posted @ 2017-09-28 16:16  一串字符串  阅读(563)  评论(0编辑  收藏  举报