剑指Offer利用两个栈实现一个队列

题目:用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入元素和在队列头部删除节点的功能。

 1 template <typename T>class CQueue
 2 {
 3 public:
 4     CQueue(void);
 5     ~CQueue(void);
 6 
 7     void appendTail(const T& element);
 8     T deleteHead();
 9 
10 private:
11     stack<T> stack1;
12     stack<T> stack2;
13 };

思路:栈是先进后出,而队列是先进先出的,而要用栈实现队列的话,两步操作如下:

进队列:第一个栈stack1专门用来压入数据;

出队列:要把队列头部元素输出,而这个头部会在stack1中的底部,因此我们需要利用辅助栈stack2 ,把stack1元素依次压入stack2,这样原来stack1中的底部元素变成stack2的栈顶,而这就是队列的head,将之输出即可。
    上面分析是针对stack2空的情况,若stack2非空,则要继续把stack2中元素依次pop出来。

实现代码:

 1 //进队列
 2 template <typename T> void CQueue<T>::appendTail(const T& element)
 3 {
 4     stack1.push(element);
 5 }
 6 //出队列
 7 template <typename T> T CQueue<T>::deleteHead()
 8 {
 9     if (stack2.empty())
10     {
11         //若stack2是空的,则把stack1的元素copy过来
12         while (!stack1.empty())
13         {
14             T& data = stack1.top();
15             stack1.pop();
16             stack2.push(data);
17         }
18     }
19     if (stack2.empty())
20     {
21         throw new exception("queue is empty");
22     }
23     //取stack2栈顶元素,即队列的head
24     T head = stack2.top();
25     stack2.pop();
26     return head;
27 
28 }


腾讯实习生一面的时候被问了这个问题,好像这个考得比较多。

一面的时候还问了一个用数组实现队列的问题,我就说使用int 类型的Head 和 Tail 分别指向头部和尾部,进队列就Tail++,出队列就Head++;以前没对这个问题做过多的思考,总认为只要数组足够长就可以了;后来他问 如果数组大小规定,比如说Size = 10,那该如何操作?我回答的是:Head和Tail继续加下去,只是进出队列的时候,Head和Tail要对size求余;他接着问,怎么判断队列是否满了?于是我写了Tail - Head >= Size,他说OK,你的Head和Tail会不会越界?当时我一开始我以为是int范围不够,于是说改unsigned int 并增加越界的判断;他继续说,实际工作中就是用数组实现队列,腾讯用户那么多,肯定会越界的,你有没有解决办法?我当时回答使用字符串模拟,他问除了这个还有没有别的;我想了一会,才发现其实Head 和Tail 超过了Size之后,前面的值就没用了,于是说可以把Head 和Tail减掉Size的倍数,使他们维持在0~Size的范围,他才满意地点头~~接下来就被它的智力题完虐了……过了一面后,第二天的二面悲剧了。。。

 数组实现队列

code:

 1 //数组实现队列
 2 template <typename T>class CArrayQueue
 3 {
 4 public:
 5     CArrayQueue(void);
 6     ~CArrayQueue(void);
 7     
 8     void appendTail(const T& element);
 9     T deleteHead();
10 
11 private:
12     const static int nSize;
13     T Array[10];
14     int nHead;
15     int nTail;
16 };
17 template <typename T> const int CArrayQueue<T>:: nSize = 10;
18 template <typename T> CArrayQueue<T>::CArrayQueue(void)
19 {
20     this->nHead = 0;
21     this->nTail = -1;
22 
23 }
24 template <typename T> CArrayQueue<T>::~CArrayQueue(void)
25 {
26     this->nHead = 0;
27     this->nTail = -1;
28 }
29 //进队列
30 template <typename T> void CArrayQueue<T>::appendTail(const T& element)
31 {
32     if (nTail - nHead >= nSize)
33     {
34         throw new exception("Queue is full!");
35     }
36     Array[(++nTail) % nSize] = element;
37     if (nHead / nSize > 0 )
38     {
39         nTail -= nSize;
40         nHead -= nSize;
41     }    
42 }
43 //出队列
44 template <typename T> T CArrayQueue<T>::deleteHead()
45 {
46     T Head = Array[nHead++];
47     return Head;
48 }
原文地址:https://www.cnblogs.com/ivorfeng/p/3053206.html