数据结构-使用两个栈实现一个队列
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; }
运行结果:
本博文由Leon Zhang原创,若转载,请注明出处。