众所周知栈和队列是两个中不同的数据结构,栈是先入后出,队列是先入先出,虽然栈和队列有不同之处,但是他们之间也有相互的联系
两个栈实现一个队列了解一下
首先我们需要两个栈S1,S2,通过两个栈之间元素的交换从而达到先入先出的目的
所以我们对队列Queue定义为
typedef
struct
Queue
{
Stack
* S1;
Stack
* S2;
size_t
_size;
}
Queue
;
所以我们这里也要对队列进行初始化
void
QueueByTwoStackInit(
Queue
*
q
)
{
StackInit(
q
->S1);
//对栈S1进行初始化
StackInit(
q
->S2);
//对栈S2进行初始化
q
->_size = 0;
}
这里我们用S1来入元素,S2来出元素
所以这里入队列的入队就很简单,就是把元素入到S1这个栈里面,同时size++
void
QueueByTwoStackPush(
Queue
*
q
,
DataType
x
)
//入队
{
StackPush(
q
->S1,
x
);
//把x入到栈S1中
q
->_size++;
}
出队列时候我们分两种情况,
第一种情况,S2为空,我们这时候把依次S1里面的元素出栈入到S2中,那么这时候S2栈顶的元素就是最早入队的元素,出队只要对S2进行出栈即可
第二种情况就是S2中有元素,那么直接对S2栈顶元素进行出栈就行,直到S2为空时候,再次变为第一种情况,再从S1中把元素拿过来,因为出队是在S2中,所以不影响S1中的正常入队
void
QueueByTwoStackPop(
Queue
*
q
)
//出队
{
if
(
q
->_size == 0)
//队列为空时没有元素可以出队,所以直接return
return
;
if
(StackSize(
q
->S2))
//如果S2不为空
{
StackPop(
q
->S2);
//直接对S2进行出栈,size--
q
->_size--;
}
else
//S2为空时
{
while
(StackSize(
q
->S1))
//执行循环直到把S1所有元素拿到S2中
{
StackPush(
q
->S2, StackTop(
q
->S1));
//把S1栈顶元素入到S2中
StackPop(
q
->S1);
//把S1栈顶元素pop掉
}
StackPop(
q
->S2);
//当所有元素都在S2中时,对2栈顶元素出栈,size--
q
->_size--;
}
}
当然,上面利用了一些栈的函数接口,这里就只是对用两个栈实现一个队列的相关操作,栈的相关接口实现在这里就不过多涉及了