leetcode 栈和队列的互相实现
Posted Allen9012
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 栈和队列的互相实现相关的知识,希望对你有一定的参考价值。
1. 用队列实现栈
本题目来源于leetcode225. 用队列实现栈
1.1 题目描述
示例
注意和提示
1.1.1 接口函数
typedef struct
MyStack;
MyStack* myStackCreate()
void myStackPush(MyStack* obj, int x)
int myStackPop(MyStack* obj)
int myStackTop(MyStack* obj)
bool myStackEmpty(MyStack* obj)
void myStackFree(MyStack* 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);
*/
1.2 大致框架
注意要实现功能,利用先进先出的队列达成后进先出的栈
这里还是同样的,用c语言的话肯定是要先实现一下队列
1.2.1 想法和思路
这两个队列,保证在插入数据的时候,往不为空的那个队列插入,保持另一个队列是空的,出队列的时候,使前size-1个导入空队列,删除最后一个
1.2.2 具体步骤
先实现一个栈
#include <stdbool.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef int QDataType;
typedef struct QueueNode
struct QueueNode* next;
QDataType data;
QueueNode;
typedef struct Queue
QueueNode* head;
QueueNode* tail;
Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
void QueueInit(Queue* pq)
assert(pq);
pq->head = pq->tail = NULL;
void QueueDestroy(Queue* pq)
assert(pq);
QueueNode* cur = pq->head;
while (cur)
QueueNode* next = cur->next;
free(cur);
cur = next;
pq->head = pq->tail = NULL;
void QueuePush(Queue* pq, QDataType x)
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL)
printf("malloc fail\\n");
exit(-1);
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)//如果一个节点都没有
pq->head = pq->tail = newnode;
else//正经插入数据
pq->tail->next = newnode;
pq->tail = newnode;
void QueuePop(Queue* pq)
//先进的先出,就是头删
assert(pq);//空指针
assert(!QueueEmpty(pq));//空
if (pq->head->next == NULL)//一个节点的时候要特殊考虑
free(pq->head);
pq->head = pq->tail = NULL;
else
QueueNode* next = pq->head->next;
free(pq->head);
pq->head = next;
QDataType QueueFront(Queue* pq)
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
QDataType QueueBack(Queue* pq)
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
bool QueueEmpty(Queue* pq)
assert(pq);
return pq->head == NULL && pq->tail==NULL;
int QueueSize(Queue* pq)
assert(pq);
int size = 0;
QueueNode* cur = pq->head;
while (cur)
++size;
cur = cur->next;
return size;
然后处理实现栈过程
MyStack
typedef struct
Queue q1;
Queue q2;
MyStack;
myStackCreate
MyStack* myStackCreate()
MyStack*pst=(MyStack*)malloc(sizeof(MyStack));
QueueInit1(&pst->q1);
QueueInit2(&pst->q2);
return pst;
myStackPush
往不为空的队列里面入数据
void myStackPush(MyStack* obj, int x)
if(!QueueEmpty(&obj->q1))//谁空放哪里
QueuePush(&obj->q1,x);
else
QueuePush(&obj->q2,x);
myStackPop
后入的先出,所以,想法是把数据按照队列的方式先出,出到另外一个队列里面
如图,假如数据进入的顺序是1,2,3,4
先把123放到另外一个队列之中,然后把4用队列的删除pop掉就可以了
int myStackPop(MyStack* obj)
Queue*pEmpty=&obj->q1;
Queue*pNonEmpty=&obj->q2;
if(!QueueEmpty(&obj->q1))
pNonEmpty=&obj->q1;
pEmpty=&obj->q2;
while(QueueSize(pNonEmpty)>1)
//取一个插一个删一个,取一个插一个删一个
QueuePush(pEmpty,QueueFront(pNonEmpty));
QueuePop(pNonEmpty);
//最后一个干掉
int front=QueueFront(pNonEmpty);
QueuePop(pNonEmpty);
return front;
myStackTop
int myStackTop(MyStack* obj)
if(!QueueEmpty(&obj->q1))
//队尾的数据就是栈顶
return QueueBack(&obj->q1);
else
return QueueBack(&obj->q2);
myStackEmpty
都是空的才说明是空的
bool myStackEmpty(MyStack* obj)
return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
myStackFree
void myStackFree(MyStack* obj)
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
1.2.3 测试时发生的错误
解决第一个错误
显然是一个测试用例都没有通过
int myStackTop(MyStack* obj)
if(QueueEmpty(&obj->q1))//检查了一遍发现缺了感叹号,也就是Top,那如果没有!就返回了空队列肯定不对
//队尾的数据就是栈顶
return QueueBack(&obj->q1);
else
return QueueBack(&obj->q2);
但是显然这不会使得超出时间限制,所以继续检查
解决第二个错误
void myStackPush(MyStack* obj, int x)
if(QueueEmpty(&obj->q1))//谁空放哪里
QueuePush(&obj->q1,x);
else
QueuePush(&obj->q2,x);
很尴尬😅这里也忘了,一样的问题
但是还没完
解决第三个错误
既然都不是那一定是队列写错了
然后一找发现bug后直接吐血😭
为什么会在while(cur)后面加一个;
怪不得程序停不下来
int QueueSize(Queue* pq)
assert(pq);
int size = 0;
QueueNode* cur = pq->head;
while (cur);
++size;
cur = cur->next;
return size;
总算解决了心,队列要好好写啊
1.3 整体实现
#include <stdbool.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef int QDataType;
typedef struct QueueNode
struct QueueNode* next;
QDataType data;
QueueNode;
typedef struct Queue
QueueNode* head;
QueueNode* tail;
Queue;
void QueueInit(Queue* pq);
void QueueDestroy(Queue* pq);
void QueuePush(Queue* pq, QDataType x);
void QueuePop(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);
void QueueInit(Queue* pq)
assert(pq);
pq->head = pq->tail = NULL;
void QueueDestroy(Queue* pq)
assert(pq);
QueueNode* cur = pq->head;
while (cur)
QueueNode* next = cur->next;
free(cur);
cur = next;
pq->head = pq->tail = NULL;
void QueuePush(Queue* pq, QDataType x)
assert(pq);
QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
if (newnode == NULL)
printf("malloc fail\\n");
exit(-1);
newnode->data = x;
newnode->next = NULL;
if (pq->head == NULL)//如果一个节点都没有
pq->head = pq->tail = newnode;
else//正经插入数据
pq->tail->next = newnode;
pq->tail = newnode;
void QueuePop(Queue* pq)
//先进的先出,就是头删
assert(pq);//空指针
assert(!QueueEmpty(pq));//空
if (pq->head->next == NULL)//一个节点的时候要特殊考虑
free(pq->head);
pq->head = pq->tail = NULL;
else
QueueNode* next = pq->head->next;
free(pq->head);
pq->head = next;
QDataType QueueFront(Queue* pq)
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
QDataType QueueBack(Queue* pq)
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
bool QueueEmpty(Queue* pq)
assert(pq);
return pq->head == NULL && pq->tail==NULL;
int QueueSize(Queue* pq)
assert(pq);
int size = 0;
QueueNode* cur = pq->head;
while (cur)
++size;
cur = cur->next;
return size;
typedef struct
Queue q1;
Queue q2;
MyStack;
MyStack* myStackCreate()
MyStack*pst=(MyStack*)malloc(sizeof(MyStack));
QueueInit(&pst->q1);
QueueInit(&pst->q2);
return pst;
void myStackPush(MyStack* obj, int x)
if(!QueueEmpty(&obj->q1))//谁空放哪里
QueuePush(&obj->q1,x);
else
QueuePush(&obj->q2,x);
int myStackPop(MyStack* obj)
Queue*pEmpty=&obj->q1;
Queue*pNonEmpty=&obj->q2;
if(!QueueEmpty(&obj->q1))
pNonEmpty=&obj->q1;
pEmpty=&obj->q2;
while(QueueSize(pNonEmpty)>1)
//取一个插一个删一个,取一个插一个删一个
QueuePush(pEmpty,QueueFront(pNonEmpty));
QueuePop(pNonEmpty);
//最后一个干掉
int front=QueueFront(pNonEmpty);
QueuePop(pNonEmpty);
return front;
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)
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
2. 用栈实现队列
2.1 题目描述
栈和队列数据结构的相互实现[LeetCode]