题目来源:力扣
题目描述:
请你仅使用两个队列实现一个后入先出(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);
- */
运行结果:
