【数据结构初阶】队列经典习题两道

news2024/12/24 3:14:51

hello!

我是云边有个稻草人

目录

一、用队列实现栈

二、用栈实现队列

Relaxing Time !


正文开始——

一、用队列实现栈

225. 用队列实现栈 - 力扣(LeetCode)

根据题目要求,我们要用两个队列来实现栈的相关功能,push入栈,top取栈顶元素,pop出栈,empty判空。我们要利用队列的功能操作来实现,所以我们要提前手撕一个队列的代码出来。

下面我们来看一下主要操作实现的思路:

出栈:现在我们有两个队列,找到其一非空队列,将非空队列里面前 size-1个元素导入到另一个队列里面,那么原非空队列中还剩一个元素,将该元素出队列,这样就能实现出栈的操作,符合栈“后进先出”的原则,(遵守队列的规则,实现栈的功能),每进行一次出栈操作之后,都至少有一个队列为空。

//出栈
int myStackPop(MyStack* obj) {
    //找到非空队列
    Queue* empQ=&obj->q1;
    Queue* noneQ=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        empQ=&obj->q2;
        noneQ=&obj->q1;
    }
    //将非空队列里面size-1个数据导入到空队列里面
    while(QueueSize(noneQ)>1)
    {
        int front=QueueFront(noneQ);
        QueuePush(empQ,front);
        QueuePop(noneQ);
    }
    //剩下一个栈顶元素
    int Pop=QueueFront(noneQ);
    QueuePop(noneQ);
    return Pop;
}

入栈:找不为空的队列入栈。

void myStackPush(MyStack* obj, int x) {
    //入栈,往不为空的队列里面插入数据
    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    }
}

取栈顶元素:找非空队列里面的队尾元素

//找栈顶元素
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);
}

完整代码:

先手撕一个队列的完整代码,

再用两个队列来创建一个栈,

对栈进行初始化等各种操作,

最后销毁。

typedef int QDataType;
typedef struct QueueNode{
    QDataType data;
    struct QueueNode* next;
}QueueNode;

typedef struct Queue{
    QueueNode* phead;
    QueueNode* ptail;
    int size;
}Queue;

//初始化
void QueueInit(Queue* pq)
{
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

//入数据 队尾
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	//申请一个新结点
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc file!");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;

	//若队列为空
	if (pq->phead == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

//判空
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead == NULL;
}

//出队列 队头
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	//当队列只有一个元素时,避免ptail成为野指针
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QueueNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	--pq->size;
}


//取队头元素
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->phead->data;
}

//取队尾元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->ptail->data;
}

//队列里有效元素的个数
int QueueSize(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->size;
}

//销毁
void QueueDestroy(Queue* pq)
{
	assert(pq);

	QueueNode* pcur = pq->phead;
	while (pcur)
	{
		QueueNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

//用两个队列来创建栈
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* empQ=&obj->q1;
    Queue* noneQ=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        empQ=&obj->q2;
        noneQ=&obj->q1;
    }
    //将非空队列里面size-1个数据导入到空队列里面
    while(QueueSize(noneQ)>1)
    {
        int front=QueueFront(noneQ);
        QueuePush(empQ,front);
        QueuePop(noneQ);
    }
    //剩下一个栈顶元素
    int Pop=QueueFront(noneQ);
    QueuePop(noneQ);
    return Pop;
}

//找栈顶元素
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);
    obj=NULL;
}

/**
 * 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);
*/

二、用栈实现队列

232. 用栈实现队列 - 力扣(LeetCode)

【思路】 

【代码】 

//创建栈的结构
typedef int STDataType;
typedef struct Stack
{
	STDataType* arr;
	int capacity;   //栈的容量
	int top;       //栈顶
}Stack;

//初始化
void StackInit(Stack* ps)
{
	assert(ps);
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
}

//销毁
void StackDestroy(Stack* ps)
{
	assert(ps);
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
}

//入数据
void StackPush(Stack* ps, STDataType x)
{
	assert(ps);

	//判断空间是否充足
	if (ps->capacity == ps->top)
	{
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc file!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}

	//此时空间充足,开始入数据
	ps->arr[ps->top++] = x;
}

//判空
bool StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->top==0;
}

//出数据
void StackPop(Stack* ps)
{
	assert(ps);
	//此处判空,要想出数据,栈中就必须有数据
	assert(!StackEmpty(ps));

	//top为栈中有效元素数据个数,指向有效元素的下一个元素,减一,有效数据就少一个
	ps->top--;
}

//取栈顶元素
STDataType StackTop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	return ps->arr[ps->top - 1];
}

//栈中有效元素的个数
int StackSize(Stack* ps)
{
	assert(ps);

	return ps->top;
}

//用两个栈创建队列
typedef struct {
    Stack PushST;
    Stack PopST;   
} MyQueue;

//队列的初始化
MyQueue* myQueueCreate() {
    MyQueue* pst=(MyQueue*)malloc(sizeof(MyQueue));
    StackInit(&pst->PushST);
    StackInit(&pst->PopST);

    return pst;
}

//入队列
void myQueuePush(MyQueue* obj, int x) {
    StackPush(&obj->PushST,x);
}

//判断PopST队列是否为空
//1)为空,就先把PushST里面的数据导入到PopST里面,再出PopST里面的栈顶数据
//2)不为空,直接出
int myQueuePop(MyQueue* obj) {
    if(StackEmpty(&obj->PopST))
    {
        //导数据
        while(!StackEmpty(&obj->PushST))
        {
            StackPush(&obj->PopST,StackTop(&obj->PushST));
            StackPop(&obj->PushST);
        }
    }
    //取栈顶元素,删除栈顶元素并返回栈顶元素
    int top=StackTop(&obj->PopST);
    StackPop(&obj->PopST);
    return top;
}

int myQueuePeek(MyQueue* obj) {
    if(StackEmpty(&obj->PopST))
    {
        //导数据
        while(!StackEmpty(&obj->PushST))
        {
            StackPush(&obj->PopST,StackTop(&obj->PushST));
            StackPop(&obj->PushST);
        }
    }
    //取栈顶元素,删除栈顶元素并返回栈顶元素
    return StackTop(&obj->PopST);
    
}

bool myQueueEmpty(MyQueue* obj) {
    return StackEmpty(&obj->PushST)&&StackEmpty(&obj->PopST);
}

void myQueueFree(MyQueue* obj) {
    StackDestroy(&obj->PushST);
    StackDestroy(&obj->PopST);
    free(obj);
    obj=NULL;
}

至此结束——


Relaxing Time !

~ 听首歌放松一下吧 ~

一起来看流星雨

爱的华尔兹_俞灏明_高音质在线试听_爱的华尔兹歌词|歌曲下载_酷狗音乐酷狗音乐为您提供由俞灏明演唱的高清音质无损爱的华尔兹mp3在线听,听爱的华尔兹,只来酷狗音乐!icon-default.png?t=N7T8https://t3.kugou.com/song.html?id=63RnxacCQV2

我是云边有个稻草人

期待与你的下一次相遇!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2039847.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚拟机上使用Ubuntu1804上编译qt5.12.9部署到jetson nano上

开发qt界面,基于Qt5.12.9,开发环境使用虚拟机加载Ubuntu1804,开发完成后的qt程序最后部署到jetson nano上,使用的通用编译器是gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu 安装编译器 本文中直接将gcc-linaro-7.5.0-2019.…

汇昌联信做拼多多店铺如何运营?

汇昌联信如何在拼多多上运营店铺,是许多电商新手和希望扩展市场的商家所关注的问题。在这个快速发展的电商平台上,掌握正确的运营策略,对于提升店铺销量、增强品牌影响力至关重要。接下来,我们将详细探讨如何有效运营拼多多店铺。…

Angular由一个bug说起之九:AWS S3 文件下载问题

引言 在现代 Web 开发中,我们经常需要处理来自全球不同地区的数据,这包括文件名中可能包含的非拉丁文字符。最近,在一个项目中,我们遇到了一个与 Amazon S3 服务相关的挑战,涉及到文件名编码的处理。当从 S3 下载文件…

Redis分布式部署方式-主从复制

分布式部署Redis方式 分布式系统,涉及到一个非常关键的问题:单点问题 单点问题:如果某个服务器,只有一个节点(只搞一个物理服务器,来部署这个服务器程序),会遇到一些困难&#xff…

多线程学习之ThreadLocal详细笔记

ThreadLocal详细笔记 一、ThreadLocal的基本概念二、ThreadLocal的独特性2.1 数据访问方式2.2 线程安全实现2.3 适用场景 三、ThreadLocal 的简单使用四、ThreadLocal 的工作原理五、ThreadLocal和内存泄漏的关系5.1 ThreadLocalMap的Entry的Key设计成弱引用5.2 弱引用会导致内…

超简单4行代码-STM32F103的HAL实现有源蜂鸣器报警

1、概述 在嵌入式项目开发中,使用蜂鸣器作为简单的报警或提示装置非常常见。根据不同的应用场景,我们可能会选择有源蜂鸣器或无源蜂鸣器。本文将重点介绍如何通过STM32F103系列单片机,利用HAL库,仅通过4行代码实现对有源蜂鸣器的…

django学习入门系列之第九点《初识MySQL》

文章目录 9.1 初识网站9.2 初识MySQL下载安装创建配置文件初始化启动MySQL服务进入mysql查看已有文件夹退出(关闭连接)忘记密码 往期回顾 9.1 初识网站 Python相关:基础、函数、数据类型、面向、模块。前端开发直观:HTML、CSS、JavaScript、jQuery:[静态…

【运维】JetBrains Gateway (Pycharm) SSH免密连接,改为免密连接

一直要求输入密码,很烦人: 如何免密连接? 1 重新打开gateway,来到这个界面点新建连接: 2 点这里设置: 3 在这一页,你可以改你的所有配置,只要设置为password并且保存密码&…

详解Redis 高可用的方式 Redis Cluster

Redis 高可用方式 Redis 提供了多种高可用性方案,主要包括以下几种方式: 主从复制(Replication) 主从复制是最基本的高可用性方案,通过将数据从一个主节点复制到多个从节点来实现数据的冗余和读写分离。主节点负责所…

数据结构--数据结构概述

一、数据结构三要素 1. 数据的逻辑结构 数据的逻辑结构是指数据元素之间的关系和组织方式,通常分为线性结构和非线性结构。 线性结构:例如线性表,其中数据元素按照顺序排列,彼此之间存在一对一的关系。 非线性结构:…

android车载手机互联投屏新专题-实战作业布置

背景: 学习了马哥的投屏实战开发课程后,大家都可以实现如下图一样的手机车机多端互联的投屏场景。 即已经实现了手机和车机投屏互动,车机上手机画面屏幕可以与手机实体屏幕一样就是常见的Mirror模式,如果不一样就是课程里面讲的扩…

解析网络流量管理方案:简化基于云的DNS负载均衡

数字化时代,网络规模和流量需求的增长,催生了用户对可用性的需求、管理员对更好的访问和管理等需求。在大型的网络应用中,为保障站点的稳定性,会为服务或站点提供多台服务器,以平均分配每台服务器上的压力,…

上门做饭小程序项目源码功能介绍

上门做饭小程序通常包含以下功能,以便用户方便地享受到上门做饭的服务: 用户注册与登录:允许用户创建账户并登录,管理个人信息和偏好。 菜品浏览与选择:提供各种菜品的列表或菜单,用户可以浏览菜品详情、价…

C++STL详解(五)——list类的具体实现

一.本次所需实现的三个类及其成员函数接口 链表首先要有结点,因此我们需要实现一个结点类。 链表要有管理结点的结构,因此我们要有list类来管理结点。 链表中还要有迭代器,而迭代器的底层其实是指针。但是我们现有的结点类无法完成迭代器的…

在VB.net中,对数据排名次,用LINQ、SortedSet,还是用SortedList速度快

标题 在VB.net中,对数据排名次,用LINQ、SortedSet,还是用SortedList速度快 正文 在VB.NET中,选择最适合你需求的排序和索引方法时,需要考虑到数据的规模、是否需要频繁地更新数据结构、以及是否只需要排序结果或还需要…

【Hadoop】建立圈内组件的宏观认识

01存储02计算03调度04其他05回忆 众多组件们构建了大规模分布式计算和存储平台。本文介绍Hadoop生态圈中各个组件的主要功能和作用,辅助学者理解每个组件的定位和用途,从而建立对圈内组件的宏观认识。梳理清楚HDFS、MapReduce、YARN、Hive、HBase、Spark…

【大模型系列篇】Transformers综述--邱锡鹏

论文标题:A Survey of Transformers 论文作者:Tianyang Lin, Yuxin Wang, Xiangyang Liu, Xipeng Qiu 论文链接:https://arxiv.org/abs/2106.04554 Transformer 在许多人工智能领域(如自然语言处理、计算机视觉和音频处理&#…

【区块链+金融服务】山西省信易贷平台 | FISCO BCOS应用案例

2022 年 8 月 8 日,山西省发展改革委按照国家的顶层设计,指导山西股权交易中心建设山西省信易贷平台,包 括三个子平台:一是建设集金融产品超市、融资需求精准匹配、融资监测等于一体的山西省融资综合信用服务平台; 二是…

微信小程序--25(WXSS模板样式了解)

一、WXSS和CSS关系 大部分特性相同 1.wxss独有 rpx尺寸单位import 样式导入 二、rpx 1.原理 rpx将所有屏幕宽度等分为750份,自动换成像素实现屏幕适配 2.rpx与px之间换算 约分计算不同设备比例不同 三、样式导入 1.语法 importt”相对路径“;…

Qt 0814作业

一、思维导图 二、登录窗口界面 自由发挥登录窗口的应用场景,实现一个登录窗口界面 要求:每行代码都有注释 【需要用到的图片或者动图,自己去网上找】 #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(par…