注:本文轉載自互聯網,有改動,感謝作者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