1、這裡所說的都是STL中的queue,stack
其中queue的特點是先進先出,它所具有的函數有:
queue<int>
void push(int elem) //向隊列中添加元素
void pop() //從隊列中刪除頭元素,即先進入的先出去
int front(); //返回隊列中的頭元素,即隊列中最先進入的元素
int back(); //返回隊列中的末尾元素,即隊列中的最後進入的元素
int size() const; //返回隊列中元素的個數
bool empty() const ; // 判斷隊列是否為空白,空返回true,非空返回false。
其中stack 的特點是後進先出,它所具有的函數有:
stack<int>
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()函數,傳回值。
下面為實現代碼:
#ifndef STACK_H
#define STACK_H
#include <queue>
#include <iostream>
template <typename T>
class Stack {
private:
std::queue<T> q1;
std::queue<T> q2;
bool q1_used, q2_used;
public:
Stack();
void push(T elem);
void pop();
T top() const;
bool empty() const;
int size() const;
};
template <typename T>
Stack<T>::Stack() {
q1_used = true;
q2_used = false;
}
template <typename T>
void Stack<T>::push(T elem) {
if(q1_used == true) {
q1.push(elem);
}
if(q2_used == true) {
q2.push(elem);
}
}
template <typename T>
void Stack<T>::pop() {
if(!q1.empty() && q1_used == true) {
while(q1.size() != 1) {
q2.push(q1.front());
q1.pop();
}
q1.pop();
q2_used = true;
q1_used = false;
return;
}
if(!q2.empty() && q2_used == true) {
while(q2.size() != 1) {
q1.push(q2.front());
q2.pop();
}
q2.pop();
q2_used = false;
q1_used = true;
return;
}
std::cout << "error! Stack::pop()" << std::endl;
}
template <typename T>
T Stack<T>::top() const {
if(!q1.empty() && q1_used == true) {
return q1.back();
}
else if(!q2.empty() && q2_used == true) {
return q2.back();
}
std::cout << "error! Stack::top()" << std::endl;
return 0;
}
template <typename T>
bool Stack<T>::empty() const {
return q1.empty() && q1_used == true || q2.empty() && q2_used == true;
}
template <typename T>
int Stack<T>::size() const {
if(!q1.empty() && q1_used == true) {
return q1.size();
}
if(!q2.empty() && q2_used == true) {
return q2.size();
}
return 0;
}
#endif
測試程式為:
#include "Stack.h"
int main() {
Stack<int> s1;
s1.push(4);
s1.push(5);
std::cout << s1.top() << ' ' << s1.size() << std::endl;
s1.pop();
std::cout << s1.top() << ' ' << s1.size() << std::endl;
s1.pop();
s1.top();
s1.pop();
s1.push(6);
s1.push(7);
s1.push(8);
std::cout << s1.top() << ' ' << s1.size() << std::endl;
s1.pop();
std::cout << s1.top() << ' ' << s1.size() << std::endl;
}
測試結果
3、使用兩個棧來實現一個隊列
(1) 使用兩個棧s1,s2,其中假定s1負責push操作, s2負責pop操作。使用一個變數back_elem來儲存最後添加的元素。
(2) 實現隊列的push操作, 每次進行添加操作,都會相應得對棧s1進行添加元素。並對back_elem賦值
(3) 實現隊列的pop操作,每次進行刪除操作,因為s2負責pop操作,
首先判斷棧s2是否為空白?
如果s2為空白,則判斷s1是否為空白?
如果s1也為空白, 則輸出錯誤資訊,此時隊列為空白。
如果s1不為空白, 則將棧s1中的所有資料存放區到s2中。執行s2.push(s1.top()), s1.pop(). 然後在對棧s2執行,s2.pop()操作,將隊列的頭元素刪除
如果s2不為空白, 則直接對s2執行 s2.pop()操作。
例如對a,b,c實現push操作,然後實現pop操作
(4)實現隊列的front()操作,方法如pop操作相同,只是在最後一步使用s2.top()傳回值。
(5)實現隊列的back()操作,因為我們變數back_elem儲存著最後一個輸入的資料,故直接將其返回。
(6)實現隊列的size()操作,和empty()操作,就是對s1,s2分別執行操作。
實現代碼:
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
#include <stack>
template<typename T>
class Queue {
private:
std::stack<T> s1;
std::stack<T> s2;
T back_elem;
public:
void push(T elem);
void pop();
T front();
T back();
int size() const;
bool empty() const;
};
template<typename T>
void Queue<T>::push(T elem) {
s1.push(elem);
back_elem = elem;
}
template<typename T>
void Queue<T>::pop() {
if(!s2.empty()) {
s2.pop();
}
else if(!s1.empty()) {
while(!s1.empty()) {
s2.push(s1.top());
s1.pop();
}
s2.pop();
}
else {
std::cout << "error pop(), empty queue!" << std::endl;
}
}
template<typename T>
T Queue<T>::front(){
if(!s2.empty()) {
return s2.top();
}
else if(!s1.empty()) {
while(!s1.empty()) {
s2.push(s1.top());
s1.pop();
}
return s2.top();
}
else {
std::cout << "error front(), empty queue!" << std::endl;
}
}
template<typename T>
T Queue<T>::back(){
if(!empty())
return back_elem;
else {
std::cout << "error back(), empty queue!" << std::endl;
return 0;
}
}
template<typename T>
int Queue<T>::size() const {
return s1.size() + s2.size();
}
template<typename T>
bool Queue<T>::empty() const {
return s1.empty() && s2.empty();
}
#endif
測試程式
#include "Queue.h"
#include <string>
int main() {
Queue<int> queue;
queue.push(4);
queue.push(5);
queue.push(6);
std::cout << queue.front() << ' ' << queue.back() << ' ' << queue.size() << std::endl;
queue.pop();
queue.pop();
std::cout << queue.front() << ' ' << queue.back() << ' ' << queue.size() << std::endl;
queue.pop();
queue.pop();
Queue<std::string> queue2;
queue2.push("Hello");
queue2.push("World");
queue2.push("!!!!");
std::cout << queue2.front() << ' ' << queue2.back() << ' ' << queue2.size() << std::endl;
queue2.pop();
queue2.pop();
std::cout << queue2.front() << ' ' << queue2.back() << ' ' << queue2.size() << std::endl;
queue2.pop();
queue2.pop();
return true;
}
測試結果: