代码随想录算法训练营第十天| 232.用栈实现队列 、 225. 用队列实现栈

本文详细介绍了如何使用两个栈分别实现先入先出队列(MyQueue)和后入先出栈(MyStack),通过模拟队列和栈的基本操作,如push、pop、peek和empty,展示了数据结构在实际问题中的应用。
摘要由CSDN通过智能技术生成

 232.用栈实现队列

题目链接/文章讲解/视频讲解:代码随想录

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

  • 你 只能 使用标准的栈操作 —— 也就是只有 push to toppeek/pop from topsize, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

 分析及思路

队列是先进先出,我们使用一个out只进行出,in只进行进。

 

初始化时,输出顶指针和输入顶指针初始化设置为-1,进栈时先加顶指针在赋值,出栈时先赋值在减顶指针。出栈时我们只在out出栈。初始化时队列为空,即OutTop和InTop = -1,即它两个都为-1时为空。释放空间时我们直接都设置为-1即可元素不用删除进行覆盖即可。

获取顶指针时,若out有元素,则顶指针所指即为队头。否则in[0]为队头元素。

代码及注释 

// 定义一个名为MyQueue的结构体
typedef struct MyQueue{
    int OutTop; // 输出栈顶索引
    int InTop; // 输入栈顶索引
    int Out[100]; // 输出栈
    int In[100]; // 输入栈
} MyQueue;

// 创建一个MyQueue结构体的指针
MyQueue* myQueueCreate() {
    MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue)); // 分配内存空间
    queue->OutTop = -1; // 初始化输出栈顶索引为-1
    queue->InTop = -1; // 初始化输入栈顶索引为-1
    return queue; // 返回指针
}

// 将元素x推入队列
void myQueuePush(MyQueue* obj, int x) {
    obj->InTop++; // 输入栈顶索引加1
    obj->In[obj->InTop] = x; // 将元素x放入输入栈
}

// 弹出队列的第一个元素
int myQueuePop(MyQueue* obj) {
    int temp; // 临时变量
    if( obj->OutTop == -1 ){ // 如果输出栈为空
        while( obj->InTop > -1 ){ // 循环直到输入栈为空
            obj->OutTop++; // 输出栈顶索引加1
            obj->Out[obj->OutTop] = obj->In[obj->InTop]; // 将输入栈的元素弹出并放入输出栈
            obj->InTop--; // 输入栈顶索引减1
        }
    }
    temp = obj->Out[obj->OutTop]; // 将输出栈的顶部元素赋给临时变量
    obj->OutTop--; // 输出栈顶索引减1
    return temp; // 返回临时变量
}

// 返回队列的第一个元素
int myQueuePeek(MyQueue* obj) {
    if(obj->OutTop > -1) // 如果输出栈不为空
        return obj->Out[obj->OutTop]; // 返回输出栈的顶部元素
    return obj->In[0]; // 如果输出栈为空,则返回输入栈的第一个元素
}

// 检查队列是否为空
bool myQueueEmpty(MyQueue* obj) {
    if( (obj->OutTop==-1) && (obj->InTop==-1) ){ // 如果输出栈和输入栈都为空
        return true; // 返回true
    }
    return false; // 否则返回false
}

// 释放队列的内存空间
void myQueueFree(MyQueue* obj) {
    obj->InTop = -1; // 输入栈顶索引重置为-1
    obj->OutTop = -1; // 输出栈顶索引重置为-1
}

225. 用队列实现栈 

题目链接/文章讲解/视频讲解:代码随想录

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

两个队列实现

分析及思路

一个进行输入和输出,另一个起到缓冲的作用。

 

代码及注释 

#define MAX_SIZE 100  // 定义栈的最大容量为100
typedef struct {  // 定义结构体 MyStack
    int front1, rear1, front2, rear2;  // 定义四个整型变量front1, rear1, front2, rear2
    int data1[MAX_SIZE], data2[MAX_SIZE];  // 定义两个整型数组data1和data2,大小为MAX_SIZE
} MyStack;  // 结构体别名为 MyStack


MyStack* myStackCreate() {  // 创建一个新的 MyStack 结构体
    MyStack* temp = (MyStack*)malloc(sizeof(MyStack));  // 分配内存给temp,大小为MyStack结构体的大小
    temp->front1 = 0;  // 将temp的front1成员赋值为0
    temp->front2 = 0;  // 将temp的front2成员赋值为0
    temp->rear1 = 0;  // 将temp的rear1成员赋值为0
    temp->rear2 = 0;  // 将temp的rear2成员赋值为0
    return temp;  // 返回指向新分配的MyStack结构体的指针
}

void myStackPush(MyStack* obj, int x) {  // 向栈中压入一个元素
    if (obj->front1 == (obj->rear1 + 1) % MAX_SIZE)  // 如果front1等于(rear1+1)%MAX_SIZE
        return;  // 退出函数
    obj->data1[obj->rear1] = x;  // 将x存入data1数组的rear1位置
    obj->rear1 = (obj->rear1 + 1) % MAX_SIZE;  // 更新rear1的位置
}

int myStackPop(MyStack* obj) {  // 从栈中弹出一个元素
    while ((obj->front1 + 1) % MAX_SIZE != obj->rear1) {  // 当front1+1对MAX_SIZE取余不等于rear1时循环
        obj->data2[obj->rear2] = obj->data1[obj->front1];  // 将data1数组的front1位置的元素存入data2数组的rear2位置
        obj->rear2 = (obj->rear2 + 1) % MAX_SIZE;  // 更新rear2的位置
        obj->front1 = (obj->front1 + 1) % MAX_SIZE;  // 更新front1的位置
    }
    int temp = obj->data1[obj->front1];  // 将data1数组的front1位置的元素存入temp
    obj->front1 = (obj->front1 + 1) % MAX_SIZE;  // 更新front1的位置
    while (obj->front2 != obj->rear2) {  // 当front2不等于rear2时循环
        obj->data1[obj->rear1] = obj->data2[obj->front2];  // 将data2数组的front2位置的元素存入data1数组的rear1位置
        obj->rear1 = (obj->rear1 + 1) % MAX_SIZE;  // 更新rear1的位置
        obj->front2 = (obj->front2 + 1) % MAX_SIZE;  // 更新front2的位置
    }
    return temp;  // 返回temp
}

int myStackTop(MyStack* obj) {  // 返回栈顶元素的值
    int temp = myStackPop(obj);  // 调用myStackPop函数,并将返回值存入temp
    myStackPush(obj, temp);  // 调用myStackPush函数,将temp压入栈中
    return temp;  // 返回temp
}

void myStackFree(MyStack* obj) {  // 释放栈
    obj->front1 = obj->rear1;  // 将front1赋值为rear1
    obj->front2 = obj->rear2;  // 将front2赋值为rear2
}

bool myStackEmpty(MyStack* obj) {  // 判断栈是否为空
    if (obj->front1 == obj->rear1)  // 如果front1等于rear1
        return true;  // 返回true
    return false;  // 否则返回false
}

 一个队列实现

由于另一个队列只实现缓冲的作用,我们可以直接把取出的元素直接放到原队列中。

代码及注释

```c
#define MAX_SIZE 100  // 定义栈的最大容量为100

typedef struct {  // 定义结构体 MyStack
    int front1, rear1;  // 定义两个整型变量 front1 和 rear1
    int data1[MAX_SIZE];  // 定义一个整型数组 data1,大小为 MAX_SIZE
} MyStack;  // 结构体别名为 MyStack

MyStack* myStackCreate() {  // 创建一个新的 MyStack 结构体
    MyStack* temp = (MyStack*)malloc(sizeof(MyStack));  // 分配内存给 temp,大小为 MyStack 结构体的大小
    temp->front1 = 0;  // 将 temp 的 front1 成员赋值为 0
    temp->rear1 = 0;  // 将 temp 的 rear1 成员赋值为 0
    return temp;  // 返回指向新分配的 MyStack 结构体的指针
}

void myStackPush(MyStack* obj, int x) {  // 向栈中压入一个元素
    if (obj->front1 == (obj->rear1 + 1) % MAX_SIZE)  // 如果 front1 等于 (rear1+1)%MAX_SIZE
        return;  // 退出函数
    obj->data1[obj->rear1] = x;  // 将 x 存入 data1 数组的 rear1 位置
    obj->rear1 = (obj->rear1 + 1) % MAX_SIZE;  // 更新 rear1 的位置
}

int myStackPop(MyStack* obj) {  // 从栈中弹出一个元素
    int temp = obj->rear1;  // 将 rear1 的值存入 temp
    while ((obj->front1 + 1) % MAX_SIZE != temp) {  // 当 (front1+1)%MAX_SIZE 不等于 temp 时循环
        obj->data1[obj->rear1] = obj->data1[obj->front1];  // 将 data1 数组的 front1 位置的元素存入 rear1 位置
        obj->rear1 = (obj->rear1 + 1) % MAX_SIZE;  // 更新 rear1 的位置
        obj->front1 = (obj->front1 + 1) % MAX_SIZE;  // 更新 front1 的位置
    }
    int temp1 = obj->data1[obj->front1];  // 将 data1 数组的 front1 位置的元素存入 temp1
    obj->front1 = (obj->front1 + 1) % MAX_SIZE;  // 更新 front1 的位置
    return temp1;  // 返回 temp1
}

int myStackTop(MyStack* obj) {  // 返回栈顶元素的值
    int temp = myStackPop(obj);  // 调用 myStackPop 函数,并将返回值存入 temp
    myStackPush(obj, temp);  // 调用 myStackPush 函数,将 temp 压入栈中
    return temp;  // 返回 temp
}

void myStackFree(MyStack* obj) {  // 释放栈
    obj->front1 = obj->rear1;  // 将 front1 赋值为 rear1
}

bool myStackEmpty(MyStack* obj) {  // 判断栈是否为空
    if (obj->front1 == obj->rear1)  // 如果 front1 等于 rear1
        return true;  // 返回 true
    return false;  // 否则返回 false
}
```

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值