一、栈与队列的特点
(一)栈
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。
进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。不含任何元素的栈称为空
栈,栈又称为后进先出的线性表。
栈的特点:后进先出(LIFO)
(二)队列
队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作
的特殊线性表。进行插入操作的一端称为队尾,通常称为入队列;进行删除操作的一端称为队头,通常称为出队列。
队列的特点:先进先出(FIFO)
二、用两个栈实现一个队列
利用栈与队列的特殊特性,在实现栈与队列的转换之时,只需改变元素的出队列顺序即可
例如有两个栈s1与s2
(1)元素入队列:将入栈元素放在s1中,只是利用s1作为元素的入栈
(2)元素出队列:在栈中,元素先进后出,而在队列中,元素先进先出,因此再出队列之时,借助s2,将栈中的元素进行反置,如果栈s2中有元素,则将s2的栈顶元素删除,如果s2为空栈,则将s1中的元素依次压入到s2中,
直到s1为空,最后在将s2中的栈顶元素弹出即可
(3)取队列的头元素:如果s2不为空,则取s2的栈顶元素,如果s2为空,则将s1中的元素依次压入到s2中,再取s2的栈顶元素即可
(4)取队尾元素:如果s1不为空,取s1的栈顶元素即可,如果s1为空而s2不为空,则将s2中的元素压入到s1中,再取s1的栈顶元素即可
(5)求队列中元素的总个数:即s1中元素的总个数+s2中元素的总个数
(6)判断队列是否为空:如果s1与s2都为空,则队列就为空
主要代码如下所示:
//用两个栈实现一个队列
template<class T>
class Queue
{
public:
Queue()
{}
void Push(const T&data)
{
s1.push(data);
}
void Pop()
{
if (!s2.empty())
{
s2.pop();
return;
}
while (!s1.empty())
{
while (s1.size() != 0)
{
s2.push(s1.top());
s1.pop();
}
s2.pop();
}
}
T Front()
{
if (!s2.empty())
{
return s2.top();
}
while (!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
return s2.top();
}
T Back()
{
if (!s1.empty())
{
return s1.top();
}
while (!s2.empty())
{
s1.push(s2.top());
s2.pop();
}
return s1.top();
}
size_t Size()
{
return s1.size() + s2.size();
}
bool Empty()
{
if (s1.empty() && s2.empty())
return true;
else
return false;
}
private:
stack<T> s1;
stack<T> s2;
};
测试代码如下所示:
用两个栈实现一个队列
void TestLineStack()
{
//用两个栈实现一个队列
Queue<int> s;
//孔队列
s.Pop();
if (s.Empty())
{
cout << "空" << endl;
cout << "Size=" << s.Size() << endl;
}
else
{
cout << "非空" << endl;
cout << "Front=" << s.Front() << endl;
cout << "Back=" << s.Back() << endl;
cout << "Size=" << s.Size() << endl;
}
//队列中有元素
s.Push(1);
s.Push(2);
s.Push(3);
if (s.Empty())
{
cout << "空" << endl;
cout << "Size=" << s.Size() << endl;
}
else
{
cout << "非空" << endl;
cout << "Front=" << s.Front() << endl;
cout << "Back=" << s.Back() << endl;
cout << "Size=" << s.Size() << endl;
}
//从对列中删除元素
s.Pop();
if (s.Empty())
{
cout << "空" << endl;
cout << "Size=" << s.Size() << endl;
}
else
{
cout << "非空" << endl;
cout << "Front=" << s.Front() << endl;
cout << "Back=" << s.Back() << endl;
cout << "Size=" << s.Size() << endl;
}
//添加元素
s.Push(4);
if (s.Empty())
{
cout << "空" << endl;
cout << "Size=" << s.Size() << endl;
}
else
{
cout << "非空" << endl;
cout << "Front=" << s.Front() << endl;
cout << "Back=" << s.Back() << endl;
cout << "Size=" << s.Size() << endl;
}
//删除队列中的元素直到为空
s.Pop();
s.Pop();
s.Pop();
if (s.Empty())
{
cout << "空" << endl;
cout << "Size=" << s.Size() << endl;
}
else
{
cout << "非空" << endl;
cout << "Front=" << s.Front() << endl;
cout << "Back=" << s.Back() << endl;
cout << "Size=" << s.Size() << endl;
}
}
结果如下所示:
三、利用两个队列实现一个栈
利用两个队列实现一个栈中,将一个队列作为使用队列,一个队列作为空置队列,即利用两个标记值,判断队列的使用情况
例如有两个队列q1,q1_used,q2,q2_used,初始值设为q1_used=true,q2_used=false,因此在最初之时,默认将元素放在q1中
(1)元素入栈:将所有元素放在使用的队列中
(2)元素出栈:如果当前q1为使用的队列,将队列q1中的元素按照队列的特性依次放入到q2中,直至队列q1只有一个元素为止,删除q1中的最后一个元素,最后修改q1与q2的使用状态,
如果q2为当前使用的队列,情况与上面相同。
(3)取栈顶元素:即取非空队列中的队尾元素
(4)求栈中元素个数的多少:即取非空队列中元素的个数
(5)判断栈是否为空:如果q1与q2都为空,则栈就为空
主代码如下所示:
//用两个队列实现一个栈
template<class T>
class Stack
{
public:
Stack()
{
q1_used = true;//作为入队列
q2_used = false;
}
void Push(const T&data)
{
if (q1_used == true)
{
q1.push(data);
return;
}
if (q2_used == true)
{
q2.push(data);
return;
}
}
void Pop()
{
if (!q1.empty())
{
while (q1.front() != q1.back())
{
q2.push(q1.front());
q1.pop();
}
q1.pop();
q1_used = false;
q2_used = true;
return;
}
if (!q2.empty())
{
while (q2.front() != q2.back())
{
q1.push(q2.front());
q2.pop();
}
q2.pop();
q1_used = true;
q2_used = false;
return;
}
return;
}
T Top()
{
if (!q1.empty())
return q1.back();
if (!q2.empty())
return q2.back();
return NULL;
}
size_t Size()
{
if (!q1.empty())
{
return q1.size();
}
if (!q2.empty())
{
return q2.size();
}
return 0;
}
bool Empty()
{
if (q1.empty() && q2.empty())
return true;
else
false;
}
private:
queue<T> q1;
bool q1_used;
queue<T> q2;
bool q2_used;
};
测试代码如下所示:
//用两个队列实现一个栈
void TestStackLine()
{
Stack<int> s;
//空栈
s.Pop();
if (s.Empty())
{
cout << "空" << endl;
cout << "Size=" << s.Size() << endl;
}
else
{
cout << "非空" << endl;
cout <<"Top="<< s.Top() << endl;
cout << "Size=" << s.Size() << endl;
}
//往栈中添加元素
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
s.Push(5);
s.Push(7);
if (s.Empty())
{
cout << "空" << endl;
cout << "Size=" << s.Size() << endl;
}
else
{
cout << "非空" << endl;
cout << "Top=" << s.Top() << endl;
cout << "Size=" << s.Size() << endl;
}
//删除栈中元素
s.Pop();
//s.Pop();
if (s.Empty())
{
cout << "空" << endl;
cout << "Size=" << s.Size() << endl;
}
else
{
cout << "非空" << endl;
cout << "Top=" << s.Top() << endl;
cout << "Size=" << s.Size() << endl;
}
//删除栈中元素直至为空
s.Pop();
s.Pop();
s.Pop();
s.Pop();
s.Pop();
s.Pop();
if (s.Empty())
{
cout << "空" << endl;
cout << "Size=" << s.Size() << endl;
}
else
{
cout << "非空" << endl;
cout << "Top=" << s.Top() << endl;
cout << "Size=" << s.Size() << endl;
}
}
结果如下所示:
只有不停的奔跑,才能不停留在原地!!!

本文介绍了如何使用两个栈实现一个队列,以及如何使用两个队列实现一个栈。详细阐述了各自的操作流程,包括入栈、出栈、入队、出队等操作,并给出了主要的代码实现和测试结果。

被折叠的 条评论
为什么被折叠?



