广州市住房城乡建设局网站做网络推广为什么会被抓
用队列实现栈
- 题目
- 解题思路
- 1. `push`
- 2. `pop`
- 3. `empty`
- Code
- Queue.h
- Queue.c
- Stack.c
题目
225. 用队列实现栈
请你仅使用两个队列实现一个后入先出(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(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。注意:
-
你只能使用队列的标准操作 —— 也就是
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
解题思路
使用两个队列 queue1
和 queue2
来模拟栈的行为。队列遵循先进先出(FIFO)原则,而栈遵循后进先出(LIFO)原则,所以需要通过特定的操作来转换这种特性。
1. push
- 目的:将元素
x
压入栈顶。 - 思路:选择非空队列(如果两个队列都为空,则任选一个),将
x
加入该队列的尾部。
2. pop
- 目的:移除并返回栈顶元素。
- 思路:
- 队列是 FIFO ,栈顶元素在队列的尾部。要将除了最后一个元素之外的其他元素都移动到另一个队列中。将
nonempty
中的元素依次出队并加入到empty
中,直到nonempty
中只剩下一个元素,这个元素就是栈顶元素。 - 将
nonempty
中剩下的这个元素出队并返回。
- 队列是 FIFO ,栈顶元素在队列的尾部。要将除了最后一个元素之外的其他元素都移动到另一个队列中。将
3. empty
- 目的:判断栈是否为空。
- 思路:由于栈是由两个队列模拟的,当两个队列都为空时,栈才为空。所以只需要检查
queue1
和queue2
是否都为空即可。
Code
Queue.h
typedef int QDataType;
typedef struct QueueNode
{struct QueueNode* next;QDataType data;
}QNode;typedef struct Queue
{QNode* phead;QNode* ptail;int size;
}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);
Queue.c
void QueueInit(Queue* pq) {assert(pq);pq->phead = NULL;pq->ptail = NULL;pq->size = 0;
}void QueueDestory(Queue* pq) {assert(pq);QNode* cur = pq->phead;while (cur) {QNode* next = cur->next;free(cur);cur = next;}pq->phead = pq->ptail = NULL;pq->size = 0;
}void QueuePush(Queue* pq, QDataType x) {assert(pq);QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL) {perror("malloc fail\n");return;}newnode->data = x;newnode->next = NULL;if (pq->ptail == NULL) {assert(pq->phead == NULL);pq->phead = pq->ptail = newnode;}else {pq->ptail->next = newnode;pq->ptail = newnode;}pq->size++;
}void QueuePop(Queue* pq) {assert(pq);assert(!QueueEmpty(pq));// one nodeif (pq->phead->next == NULL) {free(pq->phead);pq->phead = pq->ptail = NULL;}// more nodeelse {QNode* next = pq->phead->next;free(pq->phead);pq->phead = next;}pq->size--;
}QDataType QueueFront(Queue* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->phead->data;
}
QDataType QueueBack(Queue* pq) {assert(pq);assert(!QueueEmpty(pq));return pq->ptail->data;
}
int QueueSize(Queue* pq) {assert(pq);return pq->size;
}
bool QueueEmpty(Queue* pq) {assert(pq);//return pq->phead == NULL && pq->ptail == NULL;return pq->size == 0;
}
Stack.c
typedef struct {Queue q1;Queue q2;
} MyStack;MyStack* myStackCreate() {MyStack* obj = (MyStack*)malloc(sizeof(MyStack));if(obj == NULL){perror("malloc fail");return NULL;}QueueInit(&obj->q1);QueueInit(&obj->q2);return obj;
}void myStackPush(MyStack* obj, int x) {if(!QueueEmpty(&obj->q1)){QueuePush(&obj->q1, x);}else{QueuePush(&obj->q2, x);}
}int myStackPop(MyStack* obj) {Queue* pEmptyQ = &obj->q1;Queue* pNonEmptyQ = &obj->q2;if(!QueueEmpty(&obj->q1)){pEmptyQ = &obj->q2;pNonEmptyQ = &obj->q1;}while(QueueSize(pNonEmptyQ)>1){QueuePush(pEmptyQ,QueueFront(pNonEmptyQ));QueuePop(pNonEmptyQ);}int top = QueueBack(pNonEmptyQ);QueuePop(pNonEmptyQ);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);
}