使用队列实现栈的下列操作:
push(x) -- 元素 x 入栈
pop() -- 移除栈顶元素
top() -- 获取栈顶元素
empty() -- 返回栈是否为空
注意:
你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。
定义两个队列q1,q2,入元素时,往两个队列中非空的队列中入元素,否则无法保证队列中元素正确的顺序。
出元素时,将非空队列中前n-1个元素导入空的队列中,再出非空队列中的队头元素,如此反复执行,即可实现栈“后进先出”的特点。
typedef int QDataType;
typedef struct QueueNode
{
QDataType _data;
struct QueueNode* _next;
}QueueNode;
typedef struct Queue
{
QueueNode* _head;
QueueNode* _tail;
}Queue;
//队列的初始化
void QueueInit(Queue* pq)
{
assert(pq);
pq->_head = (QueueNode*)malloc(sizeof(QueueNode));
assert(pq->_head);
pq->_tail = pq->_head;
pq->_head->_next = NULL;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QueueNode* cur = pq->_head;
while (cur)
{
QueueNode* next = cur->_next;
free(cur);
cur = next;
}
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
assert(newnode);
newnode->_data = x;
newnode->_next = NULL;
pq->_tail->_next = newnode;
pq->_tail = newnode;
}
int QueueEmpty(Queue* pq)
{
return pq->_head != pq->_tail;
}
int QueueSize(Queue* pq)
{
int count = 0;
if (QueueEmpty(pq) == 0)
return 0;
else
{
QueueNode* cur = pq->_head->_next;
while (cur)
{
++count;
cur = cur->_next;
}
}
return count;
}
void QueuePop(Queue* pq)
{
QueueNode*cur = NULL;
assert(pq);
if (QueueEmpty(pq) == 0)
return;
cur = pq->_head->_next;//保存队头的第一个元素
if (pq->_tail == cur)//若队列中只有一个元素,让尾指针指向头指针
{
pq->_tail = pq->_head;
}
pq->_head->_next = cur->_next;//删除第一个元素
free(cur);
}
QDataType QueueFront(Queue* pq)
{
assert(pq);
return pq->_head->_next->_data;
}
//定义两个队列
typedef struct {
Queue _q1;
Queue _q2;
} MyStack;
//初始化栈和所定义的两个队列
/** Initialize your data structure here. */
MyStack* myStackCreate(int maxSize) {
MyStack* st = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&st->_q1);
QueueInit(&st->_q2);
return st;
}
/** Push element x onto stack. */
/判断两个队列中哪个为空队列,往空队列中入元素
void myStackPush(MyStack* obj, int x) {
if(QueueEmpty(&obj->_q1) != 0)
{
QueuePush(&obj->_q1,x);
}
else
{
QueuePush(&obj->_q2,x);
}
}
/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
Queue* empty = &obj->_q1;
Queue* nonempty = &obj-> _q2;
if(QueueEmpty(&obj->_q1) != 0)
{
empty = &obj-> _q2;
nonempty = &obj-> _q1;
}
//将非空队列中前n-1个元素导入空队列中
while(QueueSize(nonempty) > 1)
{
QueuePush(empty,QueueFront(nonempty));
QueuePop(nonempty);
}
int front = QueueFront(nonempty);
QueuePop(nonempty);
return front;
}
/** Get the top element. */
int myStackTop(MyStack* obj) {
Queue* empty = &obj->_q1;
Queue* nonempty = &obj-> _q2;
if(QueueEmpty(&obj->_q1) != 0)
{
empty = &obj-> _q2;
nonempty = &obj-> _q1;
}
while(QueueSize(nonempty) > 1)
{
QueuePush(empty,QueueFront(nonempty));
QueuePop(nonempty);
}
int front = QueueFront(nonempty);
QueuePush(empty,front);
QueuePop(nonempty);
return front;
}
/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->_q1) == 0 && QueueEmpty(&obj->_q2) == 0;
}
void myStackFree(MyStack* obj) {
QueueDestory(&obj->_q1);
QueueDestory(&obj->_q2);
free(obj);
}