记录《剑指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){// 插入首选非空的队列,当两个队列都空的时候,默认插入队列1if (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。