题目来源:力扣
题目描述:
请你仅使用两个队列实现一个后入先出(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(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入: ["MyStack", "push", "push", "top", "pop", "empty"] [[], [1], [2], [], [], []] 输出: [null, null, null, 2, 2, false] 解释: MyStack myStack = new MyStack(); myStack.push(1); myStack.push(2); myStack.top(); // 返回 2 myStack.pop(); // 返回 2 myStack.empty(); // 返回 False提示:
1 <= x <= 9
- 最多调用
100
次push
、pop
、top
和empty
- 每次调用
pop
和top
都保证栈不为空
思路:
栈的特点是后进先出,队列的特点是先进先出,根据这些的特点,并且让我们使用两个队列来完成栈,我们可以利用队列的特点互相倒数据来完成栈,比如一个队列里有元素1,2,3,4,5,另一个队列为空,我们此时要出栈得到5,我们可以让有数据队列的前四个元素都入到另一个队列里,然后把剩下的那一个元素出栈即可,出栈前我们可以先定义空队列和非空两个指针,用来指向对应的队列,方便后续操作,入栈的话要根据哪个队列有元素就入哪个队列,销毁要先释放两个队列的空间,然后再释放整个栈的空间,初始化要先给栈申请空间,否则就是局部变量,然后要给两个队列初始化
代码实现:
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
}Queue;
void QueueInit(Queue* pq);//初始化
void QueueDestory(Queue* pq);//销毁
void QueuePush(Queue* pq, QDataType x);//入队列
void QueuePop(Queue* pq);//出队列
QDataType QueueFront(Queue* pq);//取队头元素
QDataType QueueBack(Queue* pq);//取队尾元素
int QueueSize(Queue* pq);//取数据个数
bool QueueEmpty(Queue* pq);//判断是否为空
void QueueInit(Queue* pq)//初始化
{
assert(pq);
pq->head = pq->tail = NULL;
}
void QueueDestory(Queue* pq)//销毁
{
assert(pq);
QNode* cur = pq->head;
while (cur) {
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType x)//入队列
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL) {
printf("malloc fail\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->tail == NULL) {
pq->head = pq->tail = newnode;
}
else {
pq->tail->next = newnode;
pq->tail = newnode;
}
}
void QueuePop(Queue* pq)//出队列
{
assert(pq);
assert(pq->head);
if (pq->head->next == NULL) {
free(pq->head);
pq->head = pq->tail = NULL;
}
else {
Queue* next = pq->head->next;
free(pq->head);
pq->head = next;
}
}
QDataType QueueFront(Queue* pq)//取队头元素
{
assert(pq);
assert(pq->head);
return pq->head->data;
}
QDataType QueueBack(Queue* pq)//取队尾元素
{
assert(pq);
assert(pq->head);
return pq->tail->data;
}
int QueueSize(Queue* pq)//计算数据个数
{
assert(pq);
int size = 0;
QNode* cur = pq->head;
while (cur) {
cur = cur->next;
size++;
}
return size;
}
bool QueueEmpty(Queue* pq)//判断是否为空
{
assert(pq);
return pq->head == NULL;
}
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* ps=(MyStack*)malloc(sizeof(MyStack));
if(ps==NULL){
printf("malloc fail\n");
exit(-1);
}
QueueInit(&ps->q1);
QueueInit(&ps->q2);
return ps;
}
void myStackPush(MyStack* obj, int x) {
if(!QueueEmpty(&obj->q1)){
QueuePush(&obj->q1,x);
}else{
QueuePush(&obj->q2,x);
}
}
int myStackPop(MyStack* obj) {
Queue* emptyQ = &obj->q1;
Queue* nonemptyQ = &obj->q2;
if(!QueueEmpty(&obj->q1)){
nonemptyQ = &obj->q1;
emptyQ = &obj->q2;
}
while(QueueSize(nonemptyQ)>1){
QueuePush(emptyQ,QueueFront(nonemptyQ));
QueuePop(nonemptyQ);
}
int top=QueueFront(nonemptyQ);
QueuePop(nonemptyQ);
return top;
}
int myStackTop(MyStack* obj) {
if(!QueueEmpty(&obj->q1)){
return QueueBack(&obj->q1);
}else{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
QueueDestory(&obj->q1);
QueueDestory(&obj->q2);
free(obj);
}
/**
* Your MyStack struct will be instantiated and called as such:
* MyStack* obj = myStackCreate();
* myStackPush(obj, x);
* int param_2 = myStackPop(obj);
* int param_3 = myStackTop(obj);
* bool param_4 = myStackEmpty(obj);
* myStackFree(obj);
*/
运行结果: