棧和隊列的相互實現


注:本文轉載自互聯網,有改動,感謝作者zgh1988的整理!

以STL中Queue和Stack為例:

 

1.Queue和Stack的特點

Queue支持的操作:

     queue<int>
     void push(int elem)                              //向隊列中添加元素
     void pop()                                          //從隊列中刪除頭元素,即先進入的先出去
     int front();                                         //返回隊列中的頭元素,即隊列中最先進入的元素
     int back();                                         //返回隊列中的末尾元素,即隊列中的最后進入的元素
     int size() const;                                  //返回隊列中元素的個數
     bool empty() const ;                            // 判斷隊列是否為空,空返回true,非空返回false

 

Stack支持的操作:


    void push(int elem);                             // 向棧中添加一個元素
    void pop();                                              //刪除棧中的一個元素,即最后進入的元素
    int top() const;                                       // 返回棧中的頭元素,即最后進入的元素。
    int size() const;                                     // 返回棧中元素的個數
    bool empty() const;                             // 判斷棧是否為空,空返回true,非空返回false;

 

2.用兩個隊列實現一個棧:

     (1) 使用兩個隊列 q1, q2, 還有兩個bool變量 q1_used, q2_used,分別表示q1是否在使用,q2是否在使用,兩者只有一個在使用,另一個不在使用。初始狀態為 q1_used = true;  q2_used = false;即此時q1在使用,q2閑置。
     (2) 實現棧的push操作,首先判斷q1_used,q2_used,然后找出正在使用隊列,將其添加到隊列中。例如q1_used == true;  則將元素添加到隊列q1;  反之q2_used == true,則將元素添加到隊列q2中。
     (3) 實現棧的pop操作,首先判斷q1_used ,q2_used,找出正在使用的隊列,然后將在使用的隊列元素取出來,放到閑置的隊列中,刪除隊列最后一個元素。然后修改q1_used, q2_used.
            例如初始狀態為q1_used = true,a,b,c入棧,則將其插入隊列q1中,然后執行出棧操作pop,則將a,b從q1中出隊列,然后進入q2,將c進行pop操作。 

                                                        
     (4)執行top操作,判斷q1_used q2_used,然后找出正在使用的隊列,利用該隊列函數back(),返回棧頭元素值。
       5) 至於size()和empty()操作,就對正在使用的隊列,執行size()和empty()函數,返回值。

     

 1 #ifndef STACK_H
 2 #define STACK_H
 3 
 4 #include <queue>
 5 #include <iostream>
 6 
 7 template <typename T>
 8 class Stack {
 9 private:
10  std::queue<T> q1;
11  std::queue<T> q2;
12  bool q1_used, q2_used;
13 public:
14  Stack();
15  void push(T elem);
16  void pop();
17  T top() const;
18  bool empty() const;
19  int size() const;
20 };
21 
22 template <typename T>
23 Stack<T>::Stack() {
24  q1_used = true;
25  q2_used = false;
26 }
27 
28 template <typename T>
29 void Stack<T>::push(T elem) {
30  if(q1_used == true) {
31   q1.push(elem);
32  }
33  if(q2_used == true) {
34   q2.push(elem);
35  }
36 }
37 
38 template <typename T>
39 void Stack<T>::pop() {
40  if(!q1.empty() && q1_used == true) {
41   while(q1.size() != 1) {
42    q2.push(q1.front());
43    q1.pop();
44   }
45   q1.pop();
46   q2_used = true;
47   q1_used = false;
48   return;
49  }
50  if(!q2.empty() && q2_used == true) {
51   while(q2.size() != 1) {
52    q1.push(q2.front());
53    q2.pop();
54   }
55   q2.pop();
56   q2_used = false;
57   q1_used = true;
58   return;
59  }
60  std::cout << "error! Stack::pop()" << std::endl;
61 }
62 
63 template <typename T>
64 T Stack<T>::top() const {
65  if(!q1.empty() && q1_used == true) {
66   return q1.back();
67  }
68  else if(!q2.empty() && q2_used == true) {
69   return q2.back();
70  }
71  std::cout << "error! Stack::top()" << std::endl;
72  return 0;
73 }
74 
75 template <typename T>
76 bool Stack<T>::empty() const {
77  return q1.empty() && q1_used == true || q2.empty() && q2_used == true;
78 }
79 
80 template <typename T>
81 int Stack<T>::size() const {
82  if(!q1.empty() && q1_used == true) {
83   return q1.size();
84  }
85  if(!q2.empty() && q2_used == true) {
86   return q2.size();
87  }
88  return 0;
89 }
90 
91 #endif

 

3.兩個棧實現一個隊列:

     (1):兩個棧S1,S2,S1負責數據的壓入(Enqueue),S2負責數據的彈出(Dequeue);

     (2):初始狀態兩個棧都為空;

     (3):壓入數據時,壓入S1;

     (4):彈出數據時候,如果S2為空,則將S1中所有數據項彈出然后壓入S2(倒序進入S2),然后彈出S2的棧頂元素;如果S2不為空,則直接彈出S2棧頂元素;如果S2為空且S1為空,則隊列為空。

     例如對a,b,c實現push操作,然后實現pop操作:

                               

 

 1 #ifndef QUEUE_H
 2 #define QUEUE_H
 3 #include <iostream>
 4 #include <stack>
 5 
 6 template<typename T>
 7 class Queue {
 8 private:
 9  std::stack<T> s1;
10  std::stack<T> s2;
11  T back_elem;
12 public:
13  void push(T elem);
14  void pop();
15  T front();
16  T back();
17  int size() const;
18  bool empty() const;
19 };
20 
21 template<typename T>
22 void Queue<T>::push(T elem) {
23  s1.push(elem);
24  back_elem = elem;
25 }
26 
27 template<typename T>
28 void Queue<T>::pop() {
29  if(!s2.empty()) {
30   s2.pop();
31  }
32  else if(!s1.empty()) {
33   while(!s1.empty()) {
34    s2.push(s1.top());
35    s1.pop();
36   }
37   s2.pop();
38  }
39  else {
40   std::cout << "error pop(), empty queue!" << std::endl;
41  }
42 }
43 
44 template<typename T>
45 T Queue<T>::front(){
46  if(!s2.empty()) {
47   return s2.top();
48  }
49  else if(!s1.empty()) {
50   while(!s1.empty()) {
51    s2.push(s1.top());
52    s1.pop();
53   }
54   return s2.top();
55  }
56  else {
57   std::cout << "error front(), empty queue!" << std::endl;
58  }
59 }
60 
61 template<typename T>
62 T Queue<T>::back(){
63  if(!empty())
64   return back_elem;
65  else {
66   std::cout << "error back(), empty queue!" << std::endl;
67   return 0;
68  }
69 }
70 
71 template<typename T>
72 int Queue<T>::size() const {
73  return s1.size() + s2.size();
74 }
75 
76 template<typename T>
77 bool Queue<T>::empty() const {
78  return s1.empty() && s2.empty();
79 }
80 
81 #endif

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM