首页 > 其他分享 >StackOrQueueOJ2:用队列实现栈

StackOrQueueOJ2:用队列实现栈

时间:2025-01-20 17:57:28浏览次数:3  
标签:StackOrQueueOJ2 q1 q2 obj 队列 Queue 实现 MyStack

目录


题目描述

原题:225. 用队列实现栈
在这里插入图片描述
在这里插入图片描述

思路分析

这题我们需要知道栈和队列的差异,栈是先进后出,但队列是先进先出;
出队列和出栈有冲突:

创建由队列实现的栈

这里我们要注意:如果使用MyStack* st创建,那是局部变量,无法创建成功;

MyStack* myStackCreate() {
    //如果使用MyStack* st创建,那是局部变量,无法创建成功;
    MyStack* st = (MyStack*)malloc(sizeof(MyStack));
    if(st == NULL)
    {
        perror("malloc");
        exit(-1);
    }
    QueueInit(&st->q1);
    QueueInit(&st->q2);

    return st;
}

出栈

比如要让两个队列实现栈的功能,就拿出栈来说,如果要应该将栈顶元素4拿走。
但在队列q2中,因为只能在队头进行删除,所以只能拿走元素1.
那该怎么办呢?

在这里插入图片描述
这里我们用两个队列的形式解决:

要想pop掉队列中的元素4,我们得想办法将它变成队头元素才行,这样才可以删除掉它。而如果队列q1是空队列的话,那么我们这样做:将元素4之前的3个元素都放到队列q1中,队列q2中就只剩下元素4了,那元素4就相当于队头元素,就可以进行pop操作最终将其删除掉了,删除后队列2又变成空队列了。
而队列q1就是非空队列。而重复这样的操作就可以实现删除栈顶元素的操作了:
首先将非空队列中前n-1个元素导入空队列中,然后再pop掉非空队列中的元素。
在这里插入图片描述
在这里插入图片描述

出栈接口:

int myStackPop(MyStack* obj) {
    //假设q1为空队列,q2为非空队列
    Queue* EmptyQueue = &obj->q1;
    Queue* NonEmptyQueue = &obj->q2;
    if(QueueEmpty(&obj->q2)) //假设不成立,交换
    {
        EmptyQueue = &obj->q2;
        NonEmptyQueue = &obj->q1;
    }
    int size = QueueSize(NonEmptyQueue);
    while(size > 1)
    {
        QueuePush(EmptyQueue,QueueFront(NonEmptyQueue));
        QueuePop(NonEmptyQueue);
        --size;
    }
    QDataType ret = QueueFront(NonEmptyQueue);
    QueuePop(NonEmptyQueue);
    return ret;
}
}

压栈

我们如果想要进行压栈操作,将元素5,6压入栈顶,那该如何插入呢?

其实只要在非空队列中尾插元素即可,也就是正常的入队即可;
那我们来按照空与非空来区别两个队列,因为两个不同队列有着不同的功能:

非空队列:用来插入数据 ;
空队列:用来导数据,存数据;

void myStackPush(MyStack* obj, int x) {
    if(QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q2,x);
    }
    else
    {
        QueuePush(&obj->q1,x);
    }
}

销毁

由于栈是由两个队列构成,而队列又是由两个结点指针构成。结点又是由一个data数据和一个节点指针构成。
在这里插入图片描述
所以,我们应该先从里面开始释放,不然先释放外面的里面的空间就找不到了,所以从里到外释放。先释放两个队列,然后再释放栈的空间;

void myStackFree(MyStack* obj) {
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
}

其他接口实现也就不难了

代码展示

注:由于C语言中没有内置的队列,所以我们用C语言实现了一个栈,具体讲解可看:
初阶数据结构【队列及其接口的实现】

typedef int QDataType;

typedef struct QueueNode
{
	QDataType _data;
	struct QueueNode* _next;
}QueueNode;

typedef struct Queue
{
	QueueNode* _head;
	QueueNode* _tail;
}Queue;

// 初始化队列
void QueueInit(Queue* q);
// 销毁队列
void QueueDestroy(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列队尾元素
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);

// 初始化队列
void QueueInit(Queue* q)
{
	assert(q);
	q->_head = NULL;
	q->_tail = NULL;
}

// 销毁队列
void QueueDestroy(Queue* q)
{
	assert(q);
	QueueNode* cur = q->_head;
	while (cur)
	{
		QueueNode* next = cur->_next;
		free(cur);
		cur = next;
	}
	q->_head = NULL;
	q->_tail = NULL;
}


// 队尾入队列
void QueuePush(Queue* q, QDataType x)
{
	assert(q);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newnode->_data = x;
	newnode->_next = NULL;
	if (q->_head == NULL) //当队列为空时
	{
		q->_head = newnode;
		q->_tail = newnode;
	}
	else
	{
		q->_tail->_next = newnode;
		q->_tail = newnode;
	}
}
// 队头出队列
void QueuePop(Queue* q)
{
	assert(q);
	assert(q->_head); //防止队列为空
	QueueNode* next = q->_head->_next;
	free(q->_head);
	q->_head = next;

	if (q->_head == NULL)
	{
		q->_tail = NULL;
	}
}
// 获取队列头部元素
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->_head);
	return q->_head->_data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->_tail);
	return q->_tail->_data;
}

// 检测队列是否为空,如果为空返回非零结果1,如果非空返回0 
QDataType QueueEmpty(Queue* q)
{
	assert(q);
	return q->_head == NULL ? 1 : 0;
}

// 获取队列中有效元素个数
QDataType QueueSize(Queue* q)
{
	assert(q);
	QueueNode* cur = q->_head;
	QDataType size = 0;
	while (cur)
	{
		size++;
		cur = cur->_next;
	}
	return size;
}


typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    //如果使用MyStack* st创建,那是局部变量,无法创建成功;
    MyStack* st = (MyStack*)malloc(sizeof(MyStack));
    if(st == NULL)
    {
        perror("malloc");
        exit(-1);
    }
    QueueInit(&st->q1);
    QueueInit(&st->q2);

    return st;
}

void myStackPush(MyStack* obj, int x) {
    if(QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q2,x);
    }
    else
    {
        QueuePush(&obj->q1,x);
    }
}

int myStackPop(MyStack* obj) {
    //假设q1为空队列,q2为非空队列
    Queue* EmptyQueue = &obj->q1;
    Queue* NonEmptyQueue = &obj->q2;
    if(QueueEmpty(&obj->q2)) //假设不成立,交换
    {
        EmptyQueue = &obj->q2;
        NonEmptyQueue = &obj->q1;
    }
    int size = QueueSize(NonEmptyQueue);
    while(size > 1)
    {
        QueuePush(EmptyQueue,QueueFront(NonEmptyQueue));
        QueuePop(NonEmptyQueue);
        --size;
    }
    QDataType ret = QueueFront(NonEmptyQueue);
    QueuePop(NonEmptyQueue);
    return ret;
}

int myStackTop(MyStack* obj) {
    return QueueEmpty(&obj->q1) ? QueueBack(&obj->q2) : QueueBack(&obj->q1);
}

bool myStackEmpty(MyStack* obj) {
    return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}

void myStackFree(MyStack* obj) {
    QueueDestroy(&obj->q1);
    QueueDestroy(&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);
*/

可以通过leetcode:
在这里插入图片描述


标签:StackOrQueueOJ2,q1,q2,obj,队列,Queue,实现,MyStack
From: https://blog.csdn.net/2303_78558007/article/details/145265793

相关文章

  • 【大屏可视化】系统(Vue3 + ECharts5)快速实现和应用 ️
    ......
  • 剑指offer面试题3:数组中重复的数字(Python实现)
    """面试题3:数组中重复的数字在一个长度为n的数组里所有数字都在0~n-1的范围内,某些数字是重复的,找出任意一个重复的数字"""defduplicate1(numbers:list,length:int)->int:"""修改原数组"""ifnumbers==[]orlength<=0:......
  • Spring Boot + Apache POI 实现 Excel 导出:BOM物料清单生成器(支持中文文件名、样式美
    目录引言ApachePOI操作Excel的实用技巧1.合并单元格操作2.设置单元格样式1.创建样式对象2.设置边框3.设置底色4.设置对齐方式5.设置字体样式6.设置自动换行7.应用样式到单元格3.定位和操作指定单元格4.实现标签-值的形式5.列宽设置1.设置单个列宽2.......
  • 【Aegisub】简单特效实现方法
    目录字幕横向滚动字幕竖向滚动竖向字幕字幕抖动字幕横向滚动Banner;<滚动速度>;<滚动方向>;<字体边缘模糊度>滚动速度:只能为正整数,小数负数和0无效。滚动方向:0(字幕开头从右向左移动)和1(字幕结尾从左向右移动)。字体边缘模糊度:没别的设定写0就行。一般用来做高速神言和打......
  • [Deep Learning] 使用标量回归的Sequential神经网络模型实现房价预测
    一、内容实现概述本文主要讲述使用keras库内置的Sequential(序列)模型,实现房价预测。具体实现过程如下:1.导入所需库:预先导入keras以及scikit-learn库2.导入数据:调用keras库内置的房价数据库(boston_housing)方法load_data(),导入并分割好数据3.数据预处理:对房价数据进行特征缩......
  • php毕业设计基于php的摄影门户网站设计与实现
    一、项目技术开发语言:PHP框架:原生php/thinkphp5服务器:Apache数据库:mysql5.7数据库工具:Navicat11运行软件:小皮phpStudy浏览器:谷歌浏览器二、项目内容和功能介绍在当今数字化时代,摄影艺术蓬勃发展,摄影爱好者群体日益壮大,基于PHP的摄影门户网站为他们搭建了一个汇......
  • C#实现JAVA的Synchronized
    在JAVA中,用synchronized关键字用于确保多个线程不会同时执行某个方法或代码块,从而防止并发问题,C#中有多中方法来处理这种情况。Lock语句lock语句是最常用的同步机制,类似于JAVA的synchronized。他使用一个对象作为锁,确保同一个时间只有一个线程可以进入被锁定的代码块。示......
  • 怎样用纯CSS实现禁止鼠标点击事件?
    在纯CSS中,没有直接的方法来禁止鼠标点击事件。CSS主要用于描述文档的样式,而不是控制其行为。点击事件等交互行为通常是通过JavaScript来处理的。然而,你可以使用CSS的pointer-events属性来阻止鼠标事件触发元素的默认行为。将pointer-events设置为none将使元素不再响应鼠标事件,例......
  • C语言实现顺序存储线性表
    ////Createdbystevexiaohuzhaoon2025/1/20.///****线性表的顺序存储结构实现*特点:逻辑上相邻的元素,物理上也相邻**/#include<stdio.h>#include<stdlib.h>#defineMAXSIZE100//定义线性表的最大长度//1.定义图书结构体Booktypedefstr......
  • 实现一个上下固定,中间自动填满的布局
    要实现一个上下固定,中间自动填满的布局,你可以使用CSS的Flexbox或者Grid布局。下面我将给出两种方法的示例。方法一:使用FlexboxHTML:<divclass="container"><divclass="header">Header</div><divclass="main-content">MainContent</div><div......