用队列实现栈在本质上就是实现栈“后进先出”的特点。
思路:用两个队列来实现,一个队列中存储所有的元素,另一个队列为空。为了实现后进先出的目的,我需要考虑如何把最后一个进入队列的元素(即非空队列中的最后一个元素)最先拿出来。具体实现方式是:先把非空队列中除最后一个元素之外的所有元素按顺序拿出来放到空队列中,拿出来之后立刻将其在原队列中删除。然后返回原先的非空队列中的最后一个值(很容易做到,这时该节点已成为该队列中的第一个元素)。
代码实现:
typedef struct
{
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate()//利用该函数分别创建两个队列q1和q2(由oj完成)
{
MyStack* st = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&st->q1);
QueueInit(&st->q2);
return st;
}
void myStackPush(MyStack* obj, int x)
{
if (!QueneEmpty(&obj->q1))//如果1栈不为空,将待插入的元素x插入1栈中
{
QueuePush(&obj->q1, x);
}
else//如果1栈为空,将待插入的元素x插入2栈中
{
QueuePush(&obj->q2, x);
}
}
int myStackPop(MyStack* obj)
{
Queue* emptyQ = &obj->q1;
Queue* nonemptyQ = &obj->q2;
if (!QueueEmpty(&obj->q1))//如果1队列不为空
{
emptyQ = &obj->q2;//将2队列的地址赋给指针emptyQ
nonemptyQ = &obj->q1;//将1队列的地址赋给指针nonemptyQ
}//以上五行代码实现的目的就是将指针nonemptyQ指向队列1,将指针emptyQ指向队列2
while (QueueSize(nonemptyQ) > 1)//当不为空的队列空间大于1时,会不断将非空队列中的元素挪到空队列中去,知道原先的非空队列中只剩下一个元素为止
{
QueuePush(emptyQ, QueueFront(nonemptyQ));//将不为空的队列中的第一个元素插入为空的队列中
QueuePop(nonemptyQ);//将不为空的队列中的第一个元素删除(队列中一般是头删,且这个被删除的元素就是刚刚被插入到空队列中的元素
}
int top = QueueFront(nonemptyQ);//将非空队列中的第一个元素赋值给top,此时的所谓第一个元素就是原先被挪剩下的非空链表中最后的那个元素
QueuePop(nonemptyQ);//删去非空队列的第一个元素(就是刚刚赋值给top的元素)
return top;//返回top的值
}