题目一 用两个栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:
你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/implement-queue-using-stacks、
整体分析
我们先来分析题目 跟我们上一期刷的题目区别不大
先来画图看看两个栈是什么样子的
这里进栈的顺序分别是 1 2 3 4 5
我们将这些数据迁移到另一个栈之中试试
我们可以发现 这里的数据竟然倒过来了!
那么我们取数据的顺序就变成了
1 2 3 4 5
我们发现这就刚好是跟队列删取数据的顺序一样了
所以说我们可以这样子设计这两个栈
接下来我们知道了这两个栈的基本结构了 我们来做题目试试
我们先来看第一个
第一步 初始化
我们先来看 我们创建的结构体是什么样子的
typedef struct {
ST pushst;
ST popst;
} MyQueue;
typedef int STDateType;
typedef struct Stack
{
int* a;//存储数据的大小
int Top;//栈顶
int capacity;//容量大小
}ST;
这里是两个结构体的套用
MyQueue* myQueueCreate() {
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
if(obj==NULL)
{
perror("malloc fail");
return NULL;
}
STInit(&obj->pushst);
STInit(&obj->popst);
return obj;
}
要求我们这样子 返回一个指针
那么这一步很简单 我们使用动态内存开辟一块空间就好了
之后返回一个指针指向这块空间
第二步 插入
这一步我们也讲的很明白了 插入往第一个里面插
所以说我们有以下代码
void myQueuePush(MyQueue* obj, int x) {
STPush(&obj->pushst,x);
}
直接这样子就可以了
第三步 删除
再来看图
我们一边取第一个栈的头元素放置到第二个栈中
一边删除第一个栈中的元素
知道第一个栈为空为止
代码表示如下
int myQueuePop(MyQueue* obj) {
if(STEmpty(&obj->popst))
{
//倒数据
while(!STEmpty(&obj->pushst))
{
STPush(&obj->popst,STTop(&obj->pushst));
STPop(&obj->pushst);
}
}
int front = STTop(&obj->popst);
STPop(&obj->popst);
return front;
}
第四步 返回头元素
这个很简单和删除差不多
先将所有的元素移动到第二个栈当中 返回栈的头值就可以
直接上代码
int myQueuePeek(MyQueue* obj) {
if(STEmpty(&obj->popst))
{
//倒数据
while(!STEmpty(&obj->pushst))
{
STPush(&obj->popst,STTop(&obj->pushst));
STPop(&obj->pushst);
}
}
return STTop(&obj->popst);
}
第五步 判断是否为空
这一步也很简单
两个都为空就是空了
直接上代码
bool myQueueEmpty(MyQueue* obj) {
assert(obj);
return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}
第六步 释放内存
这一步要注意了!!!
我们需要先释放开辟的两个栈的内存
之后再释放我们开辟的队列的内存
代码表示如下
void myQueueFree(MyQueue* obj) {
STDestroy(&obj->pushst);
STDestroy(&obj->popst);
free(obj);
obj = NULL;
}
代码运行结果如下
总结
并没有什么特别的难点
写的也比较顺利
收获应该是巩固了队列和栈的基本知识
源代码
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedef int STDateType;
typedef struct Stack
{
int* a;//存储数据的大小
int Top;//栈顶
int capacity;//容量大小
}ST;
void STInit(ST*ps);
void STDestroy(ST* ps);
void STPush(ST* ps, STDateType x);
void STPop(ST* ps);
int STSize(ST* ps);
bool STEmpty(ST* ps);
STDateType STTop(ST* ps);
//初始化
void STInit(ST* ps)
{
assert(ps);
ps->a = (STDateType*)malloc(sizeof(STDateType)*4);
if (ps->a == NULL)
{
perror("malloc fail");
return;
}
ps->Top = 0;//top是栈顶元素的下一个位置
ps->capacity = 4;
}
//销毁
void STDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->capacity = 0;
ps->Top = 0;
ps->a = NULL;
}
//压栈
void STPush(ST* ps, STDateType x)
{
assert(ps);
if (ps->Top == ps->capacity)
{
STDateType* tmp = (STDateType*)realloc(ps->a, sizeof(STDateType) * ps->capacity * 2);
if (tmp == NULL)
{
perror("realloc fail");
return;
}
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->Top] = x;
ps->Top++;
}
//出栈
void STPop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
ps->Top--;
}
//个数
int STSize(ST* ps)
{
assert(ps);
return ps->Top;
}
//判断空
bool STEmpty(ST* ps)
{
assert(ps);
return ps->Top==0;
}
//栈顶的位置
STDateType STTop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
return ps->a[ps->Top - 1];
}
typedef struct {
ST pushst;
ST popst;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
if(obj==NULL)
{
perror("malloc fail");
return NULL;
}
STInit(&obj->pushst);
STInit(&obj->popst);
return obj;
}
void myQueuePush(MyQueue* obj, int x) {
STPush(&obj->pushst,x);
}
int myQueuePop(MyQueue* obj) {
if(STEmpty(&obj->popst))
{
//倒数据
while(!STEmpty(&obj->pushst))
{
STPush(&obj->popst,STTop(&obj->pushst));
STPop(&obj->pushst);
}
}
int front = STTop(&obj->popst);
STPop(&obj->popst);
return front;
}
int myQueuePeek(MyQueue* obj) {
if(STEmpty(&obj->popst))
{
//倒数据
while(!STEmpty(&obj->pushst))
{
STPush(&obj->popst,STTop(&obj->pushst));
STPop(&obj->pushst);
}
}
return STTop(&obj->popst);
}
bool myQueueEmpty(MyQueue* obj) {
assert(obj);
return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}
void myQueueFree(MyQueue* obj) {
STDestroy(&obj->pushst);
STDestroy(&obj->popst);
free(obj);
obj = NULL;
}
以上便是本文所有内容了,如有错误请各位大佬不吝赐教,感谢留言