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

来源:互联网 发布:怎样查询电信网络密码 编辑:程序博客网 时间:2024/06/05 03:08

栈与队列的实现

两个栈实现队列 vs 两个队列实现栈

栈(stack)规定元素是先进后出(FILO),队列(queue)是先进先出(FIFO)。

栈的实现(数组)

实现

[cpp] view plaincopyprint?
  1. #include <iostream> 
  2. #include <algorithm> 
  3. #include <iterator> 
  4. using namespace std; 
  5. const int SIZE=10; 
  6. class stack{ 
  7. public
  8.       stack(){ 
  9.            top=0; 
  10.       } 
  11.       boolIs_empty(){ 
  12.            if(0==top) 
  13.                  returntrue; 
  14.            else 
  15.                  returnfalse; 
  16.       } 
  17.       voidPush(int elem){ 
  18.            if(top== SIZE) 
  19.                  cout<<"stackis full."<<endl; 
  20.            else
  21.                  top++; 
  22.                  array[top]=elem; 
  23.            }    
  24.       } 
  25.       intPop(){ 
  26.            if(Is_empty()) 
  27.                  cout<<"stackis empty."<<endl; 
  28.            else
  29.                  top--; 
  30.                  returnarray[top+1]; 
  31.            }    
  32.       } 
  33.       intTop(){ 
  34.            if(Is_empty()) 
  35.                  cout<<"stackis empty."<<endl; 
  36.            else
  37.                  returnarray[top]; 
  38.            }    
  39.       } 
  40. private
  41.       intarray[SIZE]; 
  42.       inttop; 
  43. }; 
  44. int main(){ 
  45.       stacks; 
  46.       s.Push(3); 
  47.       s.Push(4); 
  48.       s.Push(1); 
  49.       s.Push(10); 
  50.    cout<<s.Pop()<<endl; 
  51.       cout<<s.Pop()<<endl; 
  52.       cout<<s.Pop()<<endl; 
  53.       if(!s.Is_empty()) 
  54.            cout<<"currentTop elem: "<<s.Top()<<endl; 
  55.       cout<<s.Pop()<<endl; 
  56.       if(!s.Is_empty()) 
  57.            cout<<"currentTop elem: "<<s.Top()<<endl; 
  58.    return 0; 

结果


用链表实现栈:

[cpp] view plaincopyprint?
  1. #include <iostream> 
  2. using namespace std; 
  3. typedef int dataType; 
  4. struct node{   //链栈节点 
  5.       dataTypedata;            //数据域 
  6.       node*next;               //指针域 
  7. }; 
  8.   
  9. class ls{ 
  10. public
  11.       ls(); 
  12.       ~ls(); 
  13.       voidpush(dataType var); //压栈 
  14.       voidpop();              //出栈.出栈之前并不判断栈是否已空.需要通过isEmpty()判断 
  15.       dataTypestackTop();     //取栈顶元素,栈顶无变化.不提前判断栈是否为空 
  16.       boolisEmpty();          //判空.空返回true,反之返回false 
  17. private
  18.       node*top;               //栈顶指针.top=NULL表示为空栈 
  19. }; 
  20.   
  21. ls::ls(){ 
  22.       top= NULL;            //top=NULL表示链栈为空 
  23.   
  24. ls::~ls(){ 
  25.       node*ptr = NULL; 
  26.       while(top!= NULL){    //循环释放栈节点空间 
  27.            ptr= top->next; 
  28.            deletetop; 
  29.            top= ptr; 
  30.       } 
  31.   
  32. void ls::push(dataType var){ 
  33.       node*ptr = new node; 
  34.       ptr->data= var;        //新栈顶存值 
  35.       ptr->next= top;        //新栈顶指向旧栈顶 
  36.       top= ptr;              //top指向新栈顶 
  37.   
  38. void ls::pop(){ 
  39.       node*ptr = top->next;  //预存下一节点的指针 
  40.       deletetop;             //释放栈顶空间 
  41.       top= ptr;              //栈顶变化 
  42.   
  43. dataType ls::stackTop(){ 
  44.       returntop->data;       //返回栈顶元素,并不判断栈是否已空 
  45.   
  46. bool ls::isEmpty(){ 
  47.       returntop == NULL;     //栈顶为NULL表示栈空 
  48.   
  49. int main(){ 
  50.       lsexp; 
  51.       inti = 0; 
  52.       for(i=0;i<3;++i){ 
  53.            exp.push(i); 
  54.       } 
  55.       for(i=0;i<3;i++){ 
  56.            if(!exp.isEmpty()){ 
  57.                  cout<<exp.stackTop()<<endl; 
  58.                  exp.pop(); 
  59.            } 
  60.       } 
  61.       return0; 

队列

[cpp] view plaincopyprint?
  1. #include <iostream> 
  2. #include <algorithm> 
  3. #include <iterator> 
  4. using namespace std; 
  5. const int SIZE=10; 
  6. class queue{ 
  7. public
  8.       queue(){ 
  9.            len=0;head=0;tail=0; 
  10.       } 
  11.       voidenqueue(int elem){ 
  12.            if((tail+1)%SIZE== head) 
  13.                  cout<<"queueis full."<<endl; 
  14.            else
  15.                  array[tail]=elem; 
  16.                  tail= (tail+1)%SIZE; 
  17.                  len++; 
  18.            } 
  19.       } 
  20.       voiddequeue(){ 
  21.            if(tail== head) 
  22.                  cout<<"queueis empty."<<endl; 
  23.            else
  24.                  cout<<array[head]<<"is out."<<endl; 
  25.                  head= (head+1)%SIZE; 
  26.                  len--; 
  27.            } 
  28.       } 
  29. private
  30.       intarray[SIZE]; 
  31.       inthead; 
  32.       inttail; 
  33.       intlen; 
  34. }; 
  35.   
  36. int main(){ 
  37.       queueq; 
  38.       q.enqueue(3); 
  39.       q.enqueue(4); 
  40.       q.enqueue(1); 
  41.       q.enqueue(10); 
  42.       q.enqueue(3); 
  43.       q.enqueue(4); 
  44.       q.enqueue(1); 
  45.       q.enqueue(10); 
  46.       q.enqueue(3); 
  47.       q.enqueue(4); 
  48.       q.enqueue(1); 
  49.       q.enqueue(10); 
  50.   
  51.       q.dequeue(); 
  52.       q.dequeue(); 
  53.       q.dequeue(); 
  54.       q.dequeue(); 
  55.       q.dequeue(); 
  56.    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,如果赶上下次还是出队操作,效率会高一些。

法二:调整的工作在入队时


实现

[cpp] view plaincopyprint?
  1. #include <iostream> 
  2. #include <stack> 
  3. using namespace std; 
  4. template <class T> 
  5. class Queue{ 
  6. public
  7.       Queue(); 
  8.       ~Queue(); 
  9.       voidenqueue(const T& data); 
  10.       Tdequeue(); 
  11. //   boolisempty() const; 
  12. private
  13.       stack<T>s1; 
  14.       stack<T>s2; 
  15. }; 
  16.   
  17. template <class T> 
  18. Queue<T>::Queue(){ 
  19.   
  20. template <class T> 
  21. Queue<T>::~Queue(){ 
  22.   
  23. template <class T> 
  24. void Queue<T>::enqueue(const T&data){ 
  25.       if(s1.empty()) 
  26.            s1.push(data); 
  27.       else
  28.            while(!s1.empty()){ 
  29.                  s2.push(s1.top()); 
  30.                  s1.pop(); 
  31.            } 
  32.            s1.push(data);       
  33.       } 
  34.       while(!s2.empty()){ 
  35.            s1.push(s2.top()); 
  36.            s2.pop(); 
  37.       }    
  38.   
  39. template <class T> 
  40. T Queue<T>::dequeue(){ 
  41.       Tt; 
  42.       if(!s1.empty()){ 
  43.            t=s1.top(); 
  44.            s1.pop(); 
  45.            returnt; 
  46.       } 
  47.   
  48. int main(){ 
  49.       Queue<int>q; 
  50.       q.enqueue(1); 
  51.       q.enqueue(5); 
  52.       q.enqueue(13); 
  53.       q.enqueue(51); 
  54.       cout<<q.dequeue()<<endl; 
  55.       q.enqueue(100); 
  56.       cout<<q.dequeue()<<endl; 
  57.       cout<<q.dequeue()<<endl; 
  58.       cout<<q.dequeue()<<endl; 
  59.       cout<<q.dequeue()<<endl; 
  60.   
  61.       return0; 

结果



用两个队列实现栈

其思路和两个栈实现队列类似。

[cpp] view plaincopyprint?
  1. #include <iostream> 
  2. #include <queue> 
  3. using namespace std; 
  4. template <class T> 
  5. class stack{ 
  6. public
  7.       stack(); 
  8.       ~stack(); 
  9.       voidpush(const T& data); 
  10.       Ttop(); 
  11.       voidpop(); 
  12. private
  13.       queue<T>q1; 
  14.       queue<T>q2; 
  15. }; 
  16.   
  17.   
  18. template <class T> 
  19. stack<T>::stack(){ 
  20.   
  21. template <class T> 
  22. stack<T>::~stack(){ 
  23.   
  24. template <class T> 
  25. void stack<T>::push(const T&data){ 
  26.       if(q1.empty()) 
  27.            q1.push(data); 
  28.       else
  29.            while(!q1.empty()){ 
  30.                  q2.push(q1.front()); 
  31.                  q1.pop(); 
  32.            } 
  33.            q1.push(data); 
  34.            while(!q2.empty()){ 
  35.                  q1.push(q2.front()); 
  36.                  q2.pop(); 
  37.            }         
  38.       } 
  39.   
  40. template <class T> 
  41. void stack<T>::pop(){ 
  42.       if(!q1.empty()){ 
  43.       //   q1.front(); 
  44.            q1.pop(); 
  45.       } 
  46.   
  47. template <class T> 
  48. T stack<T>::top(){ 
  49.       Tt; 
  50.       if(!q1.empty()){ 
  51.            t=q1.front(); 
  52.            returnt; 
  53.       } 
  54.   
  55. int main(){ 
  56.       stack<int>s; 
  57.       s.push(3); 
  58.       s.push(4); 
  59.       s.push(1); 
  60.       cout<<s.top()<<endl; 
  61.       s.pop(); 
  62.       s.push(10); 
  63.       s.pop(); 
  64.    cout<<s.top()<<endl; 
  65.       s.pop(); 
  66.       cout<<s.top()<<endl; 
  67.       return0; 

结果

0 0
原创粉丝点击