压栈操作直接用队列的enqueue操作模拟。这道题的难点在于如何模拟出栈操作。
队列中的元素只有在成为队头后才有资格被dequeue操作删掉,那么这道题其实是在问,如何把一个队列的队尾移动到队头位置,删除它之后,其他元素可以按原顺序放回?把队列A的元素依次出队,并送入队列B,直到队列A中只剩下一个元素,它既是队尾又是队头,把它出队后,在反过来把队列B中元素依次出队,并送回队列A。这便是把队列A队尾元素删掉的过程。
#include "queue.h"
template<typename Object>
class StackByQueues
{
public:
StackByQueues()
{
for(int i = 0; i != NUM; ++i)
pQueue[i] = new Queue<Object>;
}
StackByQueues(const StackByQueues& rhs)
{
for(int i = 0; i != NUM; ++i)
pQueue[i] = new Queue<Object>(*(rhs.pQueue[i]));
}
StackByQueues(StackByQueues&& rhs)
{
for(int i = 0; i != NUM; ++i)
{
pQueue[i] = rhs.pQueue[i];
rhs.pQueue[i] = nullptr;
}
}
StackByQueues& operator =(const StackByQueues& rhs)
{
auto copy(rhs);
for(int i = 0; i != NUM; ++i)
std::swap(this->pQueue[i], copy.pQueue[i]);
return *this;
}
StackByQueues& operator =(StackByQueues&& rhs)
{
for(int i = 0; i != NUM; ++i)
std::swap(this->pQueue[i], rhs.pQueue[i]);
return *this;
}
~StackByQueues()
{
for(int i = 0; i != NUM; ++i)
{
if(pQueue[i])
delete pQueue[i]; //注意:这里不能写成 delete pQueue;
}
}
void push(const Object& object)
{
if(pQueue[0]->full())
std::cout << "overflow" << std::endl;
else
pQueue[0]->enqueue(object);
}
void push(Object&& object)
{
if(pQueue[0]->full())
std::cout << "overflow" << std::endl;
else
pQueue[0]->enqueue(std::move(object));
}
Object top()
{
if(pQueue[0]->empty())
{
std::cout << "underflow" << std::endl;
return Object();
}
else
{
return pQueue[0]->tail();
}
}
void pop()
{
if(pQueue[0]->empty())
return;
auto size = pQueue[0]->getSize(); //注意:写循环语句时要注意,条件变量值是否会被循环体修改,例如这里的getSize()
for(int i = 0; i != size-1; ++i)
pQueue[1]->enqueue(pQueue[0]->dequeue());
pQueue[0]->dequeue();
size = pQueue[1]->getSize();
for(int i = 0; i != size; ++i)
pQueue[0]->enqueue(pQueue[1]->dequeue());
}
bool empty() const{return pQueue[0]->empty();}
bool full() const {return pQueue[0]->full();}
private:
static constexpr int NUM = 2;
Queue<Object>* pQueue[NUM];
};
void testStackByQueues()
{
using namespace std;
struct Student
{
char name[10];
int age;
};
constexpr int NUM = 5;
Student students[NUM] = {Student{"Tom", 12},Student{"Micheal", 13},
Student{"Anna", 14},Student{"Lily", 10},
Student{"James", 19}};
StackByQueues<Student> s;
for(int i = 0; !s.full() && i != NUM; ++i)
s.push(students[i]);
decltype(s) s_copy(s);
decltype(s_copy) s_move(std::move(s_copy));
while(!s_move.empty())
{
auto stu = s_move.top();
s_move.pop();
cout << "name: " << stu.name << " age: " << stu.age << endl;
}
}
/*test output:
name: Lily age: 10
name: Anna age: 14
name: Micheal age: 13
name: Tom age: 12
*/