栈与队列的实现
两个栈实现队列 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;
}
结果
还有其它的实现:
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