栈与队列的实现__ 两个栈实现队列 vs 两个队列实现栈
来源:互联网 发布:怎样查询电信网络密码 编辑:程序博客网 时间:2024/06/05 03:08
栈与队列的实现
两个栈实现队列 vs 两个队列实现栈
栈(stack)规定元素是先进后出(FILO),队列(queue)是先进先出(FIFO)。
栈的实现(数组)
实现
- #include <iostream>
- #include <algorithm>
- #include <iterator>
- using namespace std;
- const int SIZE=10;
- class stack{
- public:
- stack(){
- top=0;
- }
- boolIs_empty(){
- if(0==top)
- returntrue;
- else
- returnfalse;
- }
- voidPush(int elem){
- if(top== SIZE)
- cout<<"stackis full."<<endl;
- else{
- top++;
- array[top]=elem;
- }
- }
- intPop(){
- if(Is_empty())
- cout<<"stackis empty."<<endl;
- else{
- top--;
- returnarray[top+1];
- }
- }
- intTop(){
- if(Is_empty())
- cout<<"stackis empty."<<endl;
- else{
- returnarray[top];
- }
- }
- private:
- intarray[SIZE];
- inttop;
- };
- int main(){
- stacks;
- s.Push(3);
- s.Push(4);
- s.Push(1);
- s.Push(10);
- cout<<s.Pop()<<endl;
- cout<<s.Pop()<<endl;
- cout<<s.Pop()<<endl;
- if(!s.Is_empty())
- cout<<"currentTop elem: "<<s.Top()<<endl;
- cout<<s.Pop()<<endl;
- if(!s.Is_empty())
- cout<<"currentTop elem: "<<s.Top()<<endl;
- return 0;
- }
结果
用链表实现栈:
- #include <iostream>
- using namespace std;
- typedef int dataType;
- struct node{ //链栈节点
- dataTypedata; //数据域
- node*next; //指针域
- };
- class ls{
- public:
- ls();
- ~ls();
- voidpush(dataType var); //压栈
- voidpop(); //出栈.出栈之前并不判断栈是否已空.需要通过isEmpty()判断
- dataTypestackTop(); //取栈顶元素,栈顶无变化.不提前判断栈是否为空
- boolisEmpty(); //判空.空返回true,反之返回false
- private:
- node*top; //栈顶指针.top=NULL表示为空栈
- };
- ls::ls(){
- top= NULL; //top=NULL表示链栈为空
- }
- ls::~ls(){
- node*ptr = NULL;
- while(top!= NULL){ //循环释放栈节点空间
- ptr= top->next;
- deletetop;
- top= ptr;
- }
- }
- void ls::push(dataType var){
- node*ptr = new node;
- ptr->data= var; //新栈顶存值
- ptr->next= top; //新栈顶指向旧栈顶
- top= ptr; //top指向新栈顶
- }
- void ls::pop(){
- node*ptr = top->next; //预存下一节点的指针
- deletetop; //释放栈顶空间
- top= ptr; //栈顶变化
- }
- dataType ls::stackTop(){
- returntop->data; //返回栈顶元素,并不判断栈是否已空
- }
- bool ls::isEmpty(){
- returntop == NULL; //栈顶为NULL表示栈空
- }
- int main(){
- lsexp;
- inti = 0;
- for(i=0;i<3;++i){
- exp.push(i);
- }
- for(i=0;i<3;i++){
- if(!exp.isEmpty()){
- cout<<exp.stackTop()<<endl;
- exp.pop();
- }
- }
- return0;
- }
队列:
- #include <iostream>
- #include <algorithm>
- #include <iterator>
- using namespace std;
- const int SIZE=10;
- class queue{
- public:
- queue(){
- len=0;head=0;tail=0;
- }
- voidenqueue(int elem){
- if((tail+1)%SIZE== head)
- cout<<"queueis full."<<endl;
- else{
- array[tail]=elem;
- tail= (tail+1)%SIZE;
- len++;
- }
- }
- voiddequeue(){
- if(tail== head)
- cout<<"queueis empty."<<endl;
- else{
- cout<<array[head]<<"is out."<<endl;
- head= (head+1)%SIZE;
- len--;
- }
- }
- private:
- intarray[SIZE];
- inthead;
- inttail;
- intlen;
- };
- int main(){
- queueq;
- q.enqueue(3);
- q.enqueue(4);
- q.enqueue(1);
- q.enqueue(10);
- q.enqueue(3);
- q.enqueue(4);
- q.enqueue(1);
- q.enqueue(10);
- q.enqueue(3);
- q.enqueue(4);
- q.enqueue(1);
- q.enqueue(10);
- q.dequeue();
- q.dequeue();
- q.dequeue();
- q.dequeue();
- q.dequeue();
- return 0;
- }
结果
用两个栈实现队列
法一:
思路:始终维护s1作为存储空间,以s2作为临时缓冲区。
步骤:入队时,将元素压入s1;出队时,将s1的元素逐个“倒入”(弹出并压入)s2,将s2的顶元素弹出作为出队元素,之后再将s2剩下的元素逐个“倒回”s1。
上述思路,可行性毋庸置疑。但有一个细节是可以优化一下的。即:在出队时,将s1的元素逐个“倒入”s2时,原在s1栈底的元素,不用“倒入”s2,可直接弹出作为出队元素返回。这样可以减少一次压栈的操作。
上述思路的一个变化:
入队时,先判断s1是否为空,如不为空,说明所有元素都在s1,此时将入队元素直接压入s1;如为空,要将s2的元素逐个“倒回”s1,再压入入队元素。
出队时,先判断s2是否为空,如不为空,直接弹出s2的顶元素并出队;如为空,将s1的元素逐个“倒入”s2,把最后一个元素弹出并出队。
相对于第一种方法,变种的s2好像比较“懒”,每次出队后,并不将元素“倒回”s1,如果赶上下次还是出队操作,效率会高一些。
法二:调整的工作在入队时
实现
- #include <iostream>
- #include <stack>
- using namespace std;
- template <class T>
- class Queue{
- public:
- Queue();
- ~Queue();
- voidenqueue(const T& data);
- Tdequeue();
- // boolisempty() const;
- private:
- stack<T>s1;
- stack<T>s2;
- };
- template <class T>
- Queue<T>::Queue(){
- }
- template <class T>
- Queue<T>::~Queue(){
- }
- template <class T>
- void Queue<T>::enqueue(const T&data){
- if(s1.empty())
- s1.push(data);
- else{
- while(!s1.empty()){
- s2.push(s1.top());
- s1.pop();
- }
- s1.push(data);
- }
- while(!s2.empty()){
- s1.push(s2.top());
- s2.pop();
- }
- }
- template <class T>
- T Queue<T>::dequeue(){
- Tt;
- if(!s1.empty()){
- t=s1.top();
- s1.pop();
- returnt;
- }
- }
- int main(){
- Queue<int>q;
- q.enqueue(1);
- q.enqueue(5);
- q.enqueue(13);
- q.enqueue(51);
- cout<<q.dequeue()<<endl;
- q.enqueue(100);
- cout<<q.dequeue()<<endl;
- cout<<q.dequeue()<<endl;
- cout<<q.dequeue()<<endl;
- cout<<q.dequeue()<<endl;
- return0;
- }
结果
用两个队列实现栈
其思路和两个栈实现队列类似。
- #include <iostream>
- #include <queue>
- using namespace std;
- template <class T>
- class stack{
- public:
- stack();
- ~stack();
- voidpush(const T& data);
- Ttop();
- voidpop();
- private:
- queue<T>q1;
- queue<T>q2;
- };
- template <class T>
- stack<T>::stack(){
- }
- template <class T>
- stack<T>::~stack(){
- }
- template <class T>
- void stack<T>::push(const T&data){
- if(q1.empty())
- q1.push(data);
- else{
- while(!q1.empty()){
- q2.push(q1.front());
- q1.pop();
- }
- q1.push(data);
- while(!q2.empty()){
- q1.push(q2.front());
- q2.pop();
- }
- }
- }
- template <class T>
- void stack<T>::pop(){
- if(!q1.empty()){
- // q1.front();
- q1.pop();
- }
- }
- template <class T>
- T stack<T>::top(){
- Tt;
- if(!q1.empty()){
- t=q1.front();
- returnt;
- }
- }
- int main(){
- stack<int>s;
- s.push(3);
- s.push(4);
- s.push(1);
- cout<<s.top()<<endl;
- s.pop();
- s.push(10);
- s.pop();
- cout<<s.top()<<endl;
- s.pop();
- cout<<s.top()<<endl;
- return0;
- }
结果
0 0
- 栈与队列的实现__ 两个栈实现队列 vs 两个队列实现栈
- 栈与队列的实现__ 两个栈实现队列 vs 两个队列实现栈
- 两个栈实现队列与两个队列实现栈
- 两个栈实现队列与两个队列实现栈
- 两个栈实现队列与两个队列实现栈
- 两个栈实现队列
- 两个队列实现栈
- 两个栈实现队列
- 两个栈实现队列
- 两个栈实现队列
- 两个队列实现栈
- 两个栈实现队列
- 两个 栈 实现队列
- 两个栈实现队列
- 两个队列实现栈
- 两个栈实现队列
- 两个栈实现队列
- 两个队列实现栈
- 查看虚拟内存的使用
- NYOJ 题目330一个简单的数学题(数学)
- [LeetCode OJ] Word Break 解题报告
- php绝对路径与相对路径之间关系的的深入研究
- Machine Learning Notes - PLA
- 栈与队列的实现__ 两个栈实现队列 vs 两个队列实现栈
- 深入C++的拷贝构造和赋值函数 (深拷贝,浅拷贝)
- Kinect for Windows SDK v2.0 开发笔记 (十一) 高清面部帧(2) 面部特征对齐
- android:padding和android:margin的区别
- 一元高次方程的求解
- Direct2D 1.1 开发笔记 特效篇(二) 简单的自定义特效
- 天天天天天天天天天天天天天天天天天天天天天天天天
- 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
- 更好哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈