✨✨欢迎大家来到Celia的博客✨✨
🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉
所属专栏:OJ题
目录
一、题目
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(
push
、top
、pop
和empty
)。实现
MyStack
类:
void push(int x)
将元素 x 压入栈顶。int pop()
移除并返回栈顶元素。int top()
返回栈顶元素。boolean empty()
如果栈是空的,返回true
;否则,返回false
。注意:
- 你只能使用队列的标准操作 —— 也就是
push to back
、peek/pop from front
、size
和is empty
这些操作。- 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
题目:用队列实现栈
二、解题思路
- 栈:先进后出
- 队列:先进先出
由于栈和队列的进出规则不同,本题需要着重解决元素进出的问题。
- 假设队列中有n个元素
- 将队列1中的n - 1个元素出队,同时将这些元素入队到队列2中
- 将队列1中的唯一一个元素出队,即拿到了模拟栈的栈顶元素
- 这时队列2有数据,队列1为空,那么在进行出队等操作时,应以有数据的队列为基准队列
- 成功模拟栈的出栈等操作
三、代码实现(队列全部代码 + 模拟代码)
typedef int QDataType; // 链式结构:表示队列 typedef struct QListNode { struct QListNode* _next; QDataType _data; }QNode; // 队列的结构 typedef struct Queue { QNode* _front; QNode* _rear; int _size; }Queue; // 初始化队列 void QueueInit(Queue* q); // 队尾入队列 void QueuePush(Queue* q, QDataType data); // 队头出队列 void QueuePop(Queue* q); // 获取队列头部元素 QDataType QueueFront(Queue* q); // 获取队列队尾元素 QDataType QueueBack(Queue* q); // 获取队列中有效元素个数 int QueueSize(Queue* q); // 检测队列是否为空,如果为空返回非零结果,如果非空返回0 int QueueEmpty(Queue* q); // 销毁队列 void QueueDestroy(Queue* q); // 初始化队列 void QueueInit(Queue* q) { assert(q); q->_front = q->_rear = NULL; q->_size = 0; } // 队尾入队列 void QueuePush(Queue* q, QDataType data) { assert(q); QNode* newnode = (QNode*)malloc(sizeof(QNode)); newnode->_data = data; newnode->_next = NULL; if (q->_front == NULL) q->_front = q->_rear = newnode; else { q->_rear->_next = newnode; q->_rear = newnode; } q->_size++; } // 队头出队列 void QueuePop(Queue* q) { assert(q); assert(q->_size); QNode* del = q->_front; q->_front = q->_front->_next; free(del); if (q->_front == NULL) q->_rear = NULL; q->_size--; } // 获取队列头部元素 QDataType QueueFront(Queue* q) { assert(q); assert(q->_size > 0); return q->_front->_data; } // 获取队列队尾元素 QDataType QueueBack(Queue* q) { assert(q); assert(q->_size); return q->_rear->_data; } // 获取队列中有效元素个数 int QueueSize(Queue* q) { assert(q); return q->_size; } // 检测队列是否为空,如果为空返回非零结果,如果非空返回0 int QueueEmpty(Queue* q) { assert(q); return !q->_size; } // 销毁队列 void QueueDestroy(Queue* q) { assert(q); if (q->_size) { QNode* del = NULL; while (q->_front != q->_rear) { del = q->_front; q->_front = q->_front->_next; free(del); } free(q->_front); q->_front = q->_rear = NULL; q->_size = 0; } } /*================================= 模拟栈 ==========================*/ //定义模拟栈 typedef struct { Queue q1;//队列1 Queue q2;//队列2 } MyStack; //建立模拟栈 MyStack* myStackCreate() { MyStack* s = (MyStack*)malloc(sizeof(MyStack)); QueueInit(&s->q1); QueueInit(&s->q2); return s; } //在非空的队列中插入元素 void myStackPush(MyStack* obj, int x) { Queue* empty = &obj->q1; Queue* nonempty = &obj->q2; if(QueueEmpty(nonempty)) { empty = &obj->q2; nonempty = &obj->q1; } QueuePush(nonempty,x); } //删除模拟栈顶的元素 int myStackPop(MyStack* obj) { Queue* empty = &obj->q1; Queue* nonempty = &obj->q2; if(QueueEmpty(nonempty))//假设法判断空队列和非空队列 { empty = &obj->q2; nonempty = &obj->q1; } while(QueueSize(nonempty) > 1)//将栈1中的n-1个元素出栈,入栈到队列2 { QueuePush(empty,QueueFront(nonempty)); QueuePop(nonempty); } int top = QueueFront(nonempty);//记录队头(栈顶)元素 QueuePop(nonempty); return top;//返回模拟栈的栈顶元素 } //取出模拟栈的栈顶元素 int myStackTop(MyStack* obj) { Queue* empty = &obj->q1; Queue* nonempty = &obj->q2; if(QueueEmpty(nonempty)) { empty = &obj->q2; nonempty = &obj->q1; } while(QueueSize(nonempty) > 1) { QueuePush(empty,QueueFront(nonempty)); QueuePop(nonempty); } int top = QueueFront(nonempty); QueuePush(empty,QueueFront(nonempty)); QueuePop(nonempty); return top; } //判空 bool myStackEmpty(MyStack* obj) { return obj->q1._size == 0 && obj->q2._size == 0; } //销毁 void myStackFree(MyStack* obj) { QueueDestroy(&obj->q1); QueueDestroy(&obj->q2); free(obj); }