题目:用两个栈实现队列。队列的声明如下,请实现它的两个函数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;
};
思路:
队列是先进先出,栈是先进后出。这题题目给出了两个栈,首先假设我们往一个栈里面压入了三个元素a、b、c。作为一个队列,如果我们压入了a、b、c,那么先出的会是a。但是栈弹出的会是c,那么该怎么输出a呢,这里注意到我们利用了一个栈,还有一个栈没有使用,如果我们把第一个栈里面的元素依次压入第二个栈里面,那么第二个栈里面从上到下会是c、b、a,只要把第二个栈的首元素弹出去就可以。再来看看插入操作,插入的时候直接把元素压入第一个栈,输出的时候将元素取出并且压入第二个栈再进行出栈操作即可。
代码:
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 new exception("queue is empty");
T head = stack2.top();
stack2.pop();
return head;
}
这道题还要学会怎么在类的外面定义函数。template<typename T> 函数类型 CQueue<T>::appendTail(const T&node)
复习:
要注意的是,在复制数据的时候用引用可以节省时间,在往stack2复制数据结束之后,要判断队列里面是否还有元素。还要注意怎么定义模板类里面的函数。
二刷代码:
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> 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();//用引用可以节省时间
stack2.push(data);
stack1.pop();
}
T head = stack2.top;
stack2.pop();
}
if(stack2.size()==0)//判断队列是否已经没有元素
throw new exception("queue is empty")
T head = stack2.top();
stack2.pop;
return head;
}
镜像问题:用两个队列实现一个栈
思路:
下面图表示两个队列,当向栈中压入a、b、c三个数之后,我们要弹出c,这个时候需要将a,b出队列queue1并且入队到queue2中,再删除c,弹出b的过程同理。压入d的时候直接入队到a后面就好了。
代码:
template<typename T>class CStack
{
public:
CStack(void);
~CStack(void);
void appendTail(const T&node);
T deleteHead();
private:
queue<T>queue1;
queue<T>queue2;
};
template<typename T> void CStack<T>::appendTail(const T&node)
{
if (queue1.size() != 0) queue1.push(node);
else queue2.push(node);
}
template<typename T> T CStack<T>::deleteHead()
{
if (queue1.size() != 0)
{
while (queue1.size()!=1)
{
T temp = queue1.front();
queue1.pop();
queue2.push(temp);
}
queue1.pop();
return temp;
}
else if (queue2.size() != 0)
{
while (queue2.size() != 1)
{
T temp = queue2.front();
queue2.pop();
queue1.push(temp);
}
queue2.pop();
return temp;
}
else throw new exception("stack is empty");
}
//这个代码是自己写的,也不知道对不对,欢迎谈论
复习:
思路还是差不多的,就是还有注意对栈为空的情况的判断。
二刷代码:
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>class CStack
{
public:
CStack(void);
~CStack(void);
void appendTail(const T&node);
T deleteHead();
private:
queue<T>queue1;
queue<T>queue2;
};
template<typename T> void CStack<T>::appendTail(const T&node)
{
if (queue1.size() != 0) queue1.push(node);
else queue2.push(node);
}
template<typename T> T CStack<T>::deleteHead()
{
if (queue1.size() != 0)
{
while (queue1.size()>1)
{
T node = queue1.front();
queue1.pop();
queue2.push(node);
}
T head = queue1.front();
queue1.pop();
}
else if(queue2.size()>1){
while (queue2.size() > 1)
{
T node = queue1.front();
queue2.pop();
queue1.push(node);
}
T head = queue2.front();
queue2.pop();
}
else throw new exception("stack is empty");
return head;
}