《剑指Offer》面试题7:用两个栈实现队列
知识点
队列和栈
题目描述
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能。
template <typename T> class CQueue
{
public:
CQueue(void);
~CQueue(void);
void appendTail(const T& node);
T deleteHead();
private:
stack<T> stack1;
stack<T> stack2;
};
解题思路
测试用例
代码(原书)
/* 《剑指Offer——名企面试官精讲典型编程题》代码
著作权所有者:何海涛*/
#include <iostream>
#include <stack>
using namespace std;
//队列的声明
template <typename T> class CQueue
{
public:
CQueue(void);
~CQueue(void);
void appendTail(const T& node);
T deleteHead();
private:
stack<T> stack1;
stack<T> stack2;
};
template <typename T> CQueue<T>::CQueue(void)
{
}
template <typename T> CQueue<T>::~CQueue(void)
{
}
//在队列尾部插入结点
template <typename T> void CQueue<T>::appendTail(const T& element)
{
stack1.push(element);
}
//在队列头部删除结点
template <typename T> T CQueue<T>::deleteHead()
{
//栈2为空,栈1不为空,将栈1的元素弹出压至栈2
if (stack2.size() <= 0)
{
while(stack1.size() > 0)
{
T& data = stack1.top();
stack1.pop();
stack2.push(data);
}
}
//弹出栈2的栈顶元素
T head = stack2.top();
stack2.pop();
return head;
}
//=======================================测试代码==========================
void Test(char actual, char expected)
{
if (actual == expected)
printf("Test passed.\n");
else
printf("Test failed.\n");
}
int main1()
{
CQueue<char> queue;
//往空的队列里添加、删除元素
queue.appendTail('a');
queue.appendTail('b');
queue.appendTail('c');
char head = queue.deleteHead();
Test(head, 'a');
head = queue.deleteHead();
Test(head, 'b');
//往非空的队列里添加、删除元素
queue.appendTail('d');
head = queue.deleteHead();
Test(head, 'c');
//连续删除元素直至队列为空
queue.appendTail('e');
head = queue.deleteHead();
Test(head, 'd');
head = queue.deleteHead();
Test(head, 'e');
system("pause");
return 0;
}
代码(牛客网)
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
#include <exception>
class Solution
{
public:
void push(int node) {
stack1.push(node); //在栈1中插入队尾元素
}
int pop() {
if(stack1.size() != 0 && stack2.size() == 0 ) //若栈2为空,将栈1中元素逐个弹出并压入栈2
{
while(stack1.size() != 0)
{
int data=stack1.top();
stack2.push(data);
stack1.pop();
}
}
int popNum = stack2.top(); //弹出栈2栈顶元素(即为队首元素)
stack2.pop();
return popNum;
}
private:
stack<int> stack1;
stack<int> stack2;
};
附加题:用两个队列实现一个栈
解题思路
代码
/*附加题*/
#include<queue>
#include<exception>
#include <iostream>
using namespace std;
//栈的声明
template <typename T> class CStack
{
public:
CStack();
~CStack();
void appendTail(const T& node);
T deleteHead();
private:
queue<T> queue1;
queue<T> queue2;
};
template<typename T> CStack<T>::CStack()
{
}
template<typename T> CStack<T>::~CStack()
{
}
// 插入元素
template<typename T> void CStack<T>::appendTail(const T& node)
{
if (queue1.size() > 0 && queue2.size() > 0)
{
//异常情况
}
else
{
//插入到非空队列,如果均为空则插入到queue2中
if (queue1.size() == 0)
{
queue2.push(node);
}
else
{
queue1.push(node);
}
}
}
template<typename T> T CStack<T>::deleteHead()
{
if (queue1.size() == 0 && queue2.size() == 0)
{
//异常情况
throw new exception("stack is empty");
}
T head;
if (queue1.size() > 0)
{
while (queue1.size()>1)
{
//queue1中的元素依次删除,并插入到queue2中,其中queue1删除最后一个元素
//相当于从栈中弹出队尾元素
T& data = queue1.front();
queue1.pop();
queue2.push(data);
}
head = queue1.front();
queue1.pop();
}
else
{
while (queue2.size()>1)
{
//queue2中的元素依次删除,并插入到queue1中,其中queue2删除最后一个元素
//相当于从栈中弹出队尾元素
T& data = queue2.front();
queue2.pop();
queue1.push(data);
}
head = queue2.front();
queue2.pop();
}
return head;
}
// ====================测试代码====================
void test(char actual, char expected)
{
if (actual == expected)
printf("Test passed.\n");
else
printf("Test failed.\n");
}
int main(int argc, char* argv[])
{
// 后进先出
CStack<char> stack;
stack.appendTail('a');
stack.appendTail('b');
stack.appendTail('c');
char head = stack.deleteHead();
test(head, 'c');
head = stack.deleteHead();
test(head, 'b');
stack.appendTail('d');
head = stack.deleteHead();
test(head, 'd');
stack.appendTail('e');
head = stack.deleteHead();
test(head, 'e');
head = stack.deleteHead();
test(head, 'a');
//空栈删除,触发异常
//head = stack.deleteHead();
getchar();
return 0;
}