栈与队列的实现__ 两个栈实现队列 vs 两个队列实现栈
来源:互联网 发布:双学位知乎 编辑:程序博客网 时间:2024/05/11 19:37
栈与队列的实现
两个栈实现队列 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,反之返回falseprivate: 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;}
结果
还有其它的实现:
http://hi.baidu.com/ozwarld/item/64b5e00c48d9b2cb90571887
http://www.cnblogs.com/kaituorensheng/archive/2013/03/02/2939690.html
参考
http://www.cnblogs.com/Anker/archive/2013/01/26/2878011.html
http://www.cnblogs.com/dartagnan/archive/2011/09/15/2177637.html
http://www.cnblogs.com/wanghui9072229/archive/2011/11/22/2259391.html
- 栈与队列的实现__ 两个栈实现队列 vs 两个队列实现栈
- 栈与队列的实现__ 两个栈实现队列 vs 两个队列实现栈
- 两个栈实现队列与两个队列实现栈
- 两个栈实现队列与两个队列实现栈
- 两个栈实现队列与两个队列实现栈
- 两个栈实现队列
- 两个队列实现栈
- 两个栈实现队列
- 两个栈实现队列
- 两个栈实现队列
- 两个队列实现栈
- 两个栈实现队列
- 两个 栈 实现队列
- 两个栈实现队列
- 两个队列实现栈
- 两个栈实现队列
- 两个栈实现队列
- 两个队列实现栈
- Huffman编码---java实现
- 中位数
- Sqlite如何修改表结构字段类型
- 感觉ibm又要改变世界了
- 图解SSH框架配置步骤
- 栈与队列的实现__ 两个栈实现队列 vs 两个队列实现栈
- Linux学习之CentOS-CentOS6.4下Mysql数据库的安装与配置
- Light OJ 1165 Digit Dancing
- Android获取Manifest中<meta-data>元素的值
- hdu4975 A simple Gaussian elimination problem.(多校第十场1005)
- 让启动画面只在第一次应用时显示, 今后不再显示
- 关于Struts2中的手工校验方法
- SQL SERVER服务角色设定
- 推荐几个不错的和前端开发相关的网站