记录《剑指offer》上的算法题。
题目描述如下:
用两个栈实现一个队列,队列的声明如下,请实现它的两个函数
appendTail
和deleteHead
,分别完成在队列尾部插入结点和在队列头部删除结点的功能。
队列的声明如下:
template <typename T>
class CQueue{
public:
CQueue(){}
~CQueue(){}
void appendTail(const T& node);
T deleteHead();
bool empty(){
return (stack1.size() == 0 && stack2.size() == 0);
}
private:
stack<T> stack1;
stack<T> stack2;
};
实现的代码如下:
template<typename T>
void CQueue<T>::appendTail(const T& node){
stack1.push(node);
}
template <typename T>
T CQueue<T>::deleteHead(){
if (stack2.size() <= 0){
while (stack1.size() > 0){
T& data = stack1.top();
stack1.pop();
stack2.push(data);
}
}
if (stack2.size() == 0)
throw std::exception("queue is empty");
T head = stack2.top();
stack2.pop();
return head;
}
实现的思路是使用stack1来存储插入的数据,而需要删除的时候,先将stack1的元素都压入stack2中,此时得到的stack2的栈顶元素就是最先插入的元素,并且依次删除stack2的元素得到的元素也是按顺序插入队列的元素顺序,也就是删除的时候先弹出stack2的元素,如果它为空,则查看stack1中是否也是空,如果是空,说明队列是空,不是空,则先弹出到stack2中,然后再依次弹出stack2的元素。
相关的一个题目是用两个队列实现一个栈,实现的思路是,压入元素的时候将元素都压入非空的队列,然后在弹出元素的时候,将非空队列的元素都压入另一个空的队列,除了队尾元素,此时队尾元素就是最后压入栈的元素,也是弹出的第一个元素。
实现代码如下:
#ifndef CSTACK_H_
#define CSTACK_H_
#include<queue>
using std::queue;
template <typename T>
class CStack{
public:
CStack(){}
~CStack(){}
void append(const T& data);
T remove();
bool empty(){
return q1.empty() && q2.empty();
}
private:
queue<T> q1;
queue<T> q2;
};
template<typename T>
void CStack<T>::append(const T& data){
// 插入首选非空的队列,当两个队列都空的时候,默认插入队列1
if (q1.empty()){
q2.push(data);
}
else{
q1.push(data);
}
}
template<typename T>
T CStack<T>::remove(){
// 删除元素的时候,将非空的队列的所有元素,除了队尾元素外,都插入到空的队列中
T res;
if (q1.empty()){
while (q2.size() > 1){
T& data = q2.front();
q2.pop();
q1.push(data);
}
res = q2.front();
q2.pop();
}
else{
while (q1.size() > 1){
T& data = q1.front();
q1.pop();
q2.push(data);
}
res = q1.front();
q1.pop();
}
return res;
}
#endif
完整的代码例子可以查看我的Github。