栈与队列的实现__ 两个栈实现队列 vs 两个队列实现栈

栈与队列的实现

两个栈实现队列   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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值