栈和队列的相关练习

用队列实现栈

在这里插入图片描述
在这里插入图片描述

首先引用上一篇博客中的队列的相关操作

typedef int QDatatype;
typedef struct QueueNode
{QDatatype data;struct QueueNode* next;
}QueueNode;typedef struct Queue
{QueueNode* head;QueueNode* tail;int size;
}Queue;void QueueInit(Queue* pq)
{assert(pq);pq->size = 0;pq->head = pq->tail = NULL;
}void QueuePush(Queue* pq, QDatatype x)
{assert(pq);QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;if (pq->head == NULL){pq->head = pq->tail = newnode;}else{pq->tail->next = newnode;pq->tail = pq->tail->next;}pq->size++;
}bool QueueEmpty(Queue* pq)
{assert(pq);return pq->head == NULL;
}void QueuePop(Queue* pq)
{assert(pq);assert(!(QueueEmpty(pq)));if (pq->head == pq->tail){free(pq->head);pq->head = pq->tail = NULL;}else{QueueNode* next = pq->head->next;free(pq->head);pq->head = next;}pq->size--;
}//取队头数据
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;
}//队列有效元素个数
int QueueSize(Queue* pq)
{assert(pq);return pq->size;
}//销毁队列
void QueueDestroy(Queue* pq)
{assert(pq);QueueNode* pcur = pq->head;while (pcur){QueueNode* next = pcur->next;free(pcur);pcur = next;}pq->head = pq->tail = NULL;pq->size = 0;
}

初始化

  1. 因为需要两个队列来实现,因此在定义时定义两个队列
  2. 在初始化时分别将两个队列进行初始化
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);}
}

出栈

  1. 寻找不为空的队列
  2. 将不为空的队列中的数据入队到另一个队列中,并将入队的元素进行出队的操作,直到该队列只剩一个元素
  3. 将该元素返回并进行出队操作
bool myStackEmpty(MyStack* obj) {return QueueEmpty(&(obj->q1)) && QueueEmpty(&(obj->q2));
}
int myStackPop(MyStack* obj) {MyStack* emq=&obj->q1;MyStack* fuq=&obj->q2;if(!QueueEmpty(&obj->q1)){emq=&obj->q2;fuq=&obj->q1;}while(QueueSize(fuq) >1){int front=QueueFront(fuq);QueuePush(emq,front);QueuePop(fuq);}int tmp=QueueFront(fuq);QueuePop(fuq);return tmp;
}

寻找栈顶元素

寻找不为空的队列,将该队列的队尾元素进行返回

int myStackTop(MyStack* obj) {if(!QueueEmpty(&obj->q1)){return QueueBack(&obj->q1);}else{return QueueBack(&obj->q2);}
}

销毁栈

将两个队列分别进行销毁,并将obj进行free并且置空

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

请添加图片描述

用栈实现队列

在这里插入图片描述
在这里插入图片描述
首先引用上上篇博客中栈的相关操作

typedef int STDatatype;typedef struct stack
{STDatatype* arr;int capacity;int top;
}ST;//初始化
void STInit(ST* ps)
{assert(ps);ps->arr = NULL;ps->capacity = ps->top = 0;
}void STDestory(ST* ps)
{assert(ps);if (ps->arr)free(ps->arr);ps->arr = NULL;ps->capacity = ps->top = 0;
}void STPush(ST* ps, STDatatype x)
{assert(ps);if (ps->capacity == ps->top){int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;STDatatype* tmp = (ST*)realloc(ps->arr, newcapacity * sizeof(ST));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newcapacity;}ps->arr[ps->top++] = x;
}bool StackEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}void STPop(ST* ps)
{assert(ps);assert(!(StackEmpty(ps)));ps->top--;
}//取栈顶元素
STDatatype StackTop(ST* ps)
{assert(ps);assert(!(StackEmpty(ps)));return ps->arr[ps->top-1];
}int STSize(ST* ps)
{assert(ps);return ps->top;
}

初始化

  1. 定义两个栈,一个用于模拟入队的操作,一个用于模拟出队的操作
  2. 初始化两个栈
typedef struct {ST pushST;ST popST;
} MyQueue;MyQueue* myQueueCreate() {MyQueue* pst=(MyQueue*)malloc(sizeof(MyQueue));STInit(&pst->pushST);STInit(&pst->popST);return pst;
}

入队

直接进行入栈操作即可

void myQueuePush(MyQueue* obj, int x) {STPush(&obj->pushST,x);
}

出队

  1. 判断出栈的栈是否为空
    1)为空,则将入栈的栈中的元素传入出栈的栈中
    2)不为空,则进行出栈的操作,并将出栈的元素的值返回
bool myQueueEmpty(MyQueue* obj) {return StackEmpty(&obj->pushST) && StackEmpty(&obj->popST);    
}int myQueuePop(MyQueue* obj) {if(StackEmpty(&obj->popST)){while(!StackEmpty(&obj->pushST)){STPush(&obj->popST,StackTop(&obj->pushST));STPop(&obj->pushST);}}int tmp=StackTop(&obj->popST);STPop(&obj->popST);return tmp;
}

寻找队头元素

思路同出队方法,只是不需要进行出栈的操作,直接返回栈顶元素的值

int myQueuePeek(MyQueue* obj) {if(StackEmpty(&obj->popST)){while(!StackEmpty(&obj->pushST)){STPush(&obj->popST,StackTop(&obj->pushST));STPop(&obj->pushST);}}return StackTop(&obj->popST);
}

销毁队

销毁两个栈,并将obj进行free并且置空

void myQueueFree(MyQueue* obj) {STDestory(&obj->pushST);STDestory(&obj->popST);free(obj);obj=NULL;
}

请添加图片描述

设计循环队列

在这里插入图片描述
在这里插入图片描述
初始化

本题可以借助数组作为底层的结构,因此在初始化时,动态开辟一个数组,并将数组的头尾和数组大小进行记录

typedef struct {int* arr;int front;int rear;int capacity;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* pst=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));pst->arr=(int*)malloc(sizeof(int)*(k+1));pst->front=pst->rear=0;pst->capacity=k;return pst;
}

插入队列元素

  1. 需要先判断数组是否已经满了
    1)若已满,则直接返回false
    2)若不满,则在数组的尾部插入数据,并将rear++,注意需要对rear取capacity+1的余数,因为该队列是循环的,最后返回true
bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->rear+1)%(obj->capacity+1)==obj->front;    
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {if(myCircularQueueIsFull(obj)){return false;}else{obj->arr[obj->rear++]=value;obj->rear %=obj->capacity+1;return true;}
}

删除队列元素

  1. 判断队列是否为空
    1)为空,则返回false
    2)不为空,则front++,注意队列的循环,将front取capacity+1的余数,并返回true
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->rear == obj->front;
}bool myCircularQueueDeQueue(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return false;}else{obj->front++;obj->front %=obj->capacity+1;return true;}
}

寻找队头元素

  1. 判断队列是否为空
  2. 为空则返回-1,不为空则返回队头元素
int myCircularQueueFront(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}return obj->arr[obj->front];
}

寻找队尾元素

  1. 判断队列是否为空
  2. 为空则返回-1,不为空则返回队尾元素,需要注意rear-1才是真正的队尾,注意队列的循环
int myCircularQueueRear(MyCircularQueue* obj) {if(myCircularQueueIsEmpty(obj)){return -1;}int prev=obj->rear-1;if(obj->rear == 0){prev=obj->capacity;}return obj->arr[prev];
}

销毁循环队列

void myCircularQueueFree(MyCircularQueue* obj) {free(obj->arr);free(obj);obj=NULL;
}

请添加图片描述

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

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

相关文章

《Java初阶数据结构》----3.<线性表---LinkedList与链表>

目录 前言 一、链表的简介 1.1链表的概念 1.2链表的八种结构 重点掌握两种 1.3单链表的常见方法 三、单链表的模拟实现 四、LinkedList的模拟实现(双链表) 4.1 什么是LinkedList 4.2LinkedList的使用 五、ArrayList和LinkedList的区别 前言 …

机器学习(五) -- 无监督学习(1) --聚类1

系列文章目录及链接 上篇:机器学习(五) -- 监督学习(7) --SVM2 下篇:机器学习(五) -- 无监督学习(1) --聚类2 前言 tips:标题前有“***”的内容…

Python 教程(四):Python运算符合集

目录 专栏列表前言1. 算术运算符2. 比较运算符3. 逻辑运算符4. 位运算符5. 赋值运算符6. 成员运算符7. 身份运算符总结 在前三篇教程中,我们学习了 Python 的基本语法和数据结构以及字符串的特性。本篇教程,我们将深入探讨 Python 中的运算符合集。 专栏…

transformers进行学习率调整lr_scheduler(warmup)

一、get_scheduler实现warmup 1、warmup基本思想 Warmup(预热)是深度学习训练中的一种技巧,旨在逐步增加学习率以稳定训练过程,特别是在训练的早期阶段。它主要用于防止在训练初期因学习率过大导致的模型参数剧烈波动或不稳定。…

搜维尔科技:Patchwork 3D-提高汽车设计的效率和创造力

提高汽车设计的效率和创造力 我们很高兴地宣布推出专为雷诺3DCommerce设计的突破性Blender插件。这款创新工具简化了将车辆配置从Patchwork 3D直接导入领先的免费 3D 建模软件Blender的过程。这款插件彰显了我们致力于提供定制解决方案以满足业务需求的承诺。 主要优点&#x…

使用图数据库Nebula Graph快速上手史上最大规模的中文知识图谱ownthink_v2教程(没写完,明天再写)

一、前言 本教程主要参考官方教程:使用图数据库 Nebula Graph 数据导入快速体验知识图谱 OwnThink (nebula-graph.com.cn) 来带着大家一步一步复现实验内容。 本教程主要使用到的数据集: ownthink/KnowledgeGraphData: 史上最大规模1.4亿中文知识图谱…

photoshop学习笔记——选区3 快速选择工具

快速选择工具 W shift W 在3种快速选择工具之间切换 对象选择工具 photoshop CC中没有这个工具,利用AI,将款选中的对象快速的提取选区,测试了一下,选区制作的非常nice快速选择工具 跟磁性套索类似,自动识别颜色相似…

ClkLog:开源用户行为分析框架,让数据分析更轻松

ClkLog:开源用户行为分析框架,让数据分析更轻松 在数据驱动的时代,找到一个好用的用户行为分析工具真是难上加难。但是今天你有福了,开源免费的 ClkLog 就是你的不二选择!本文将为你详细介绍 ClkLog 的功能特点、技术架…

Spark RPC框架详解

文章目录 前言Spark RPC模型概述RpcEndpointRpcEndpointRefRpcEnv 基于Netty的RPC实现NettyRpcEndpointRefNettyRpcEnv消息的发送消息的接收RpcEndpointRef的构造方式直接通过RpcEndpoint构造RpcEndpointRef通过消息发送RpcEndpointRef Endpoint的注册Dispatcher消息的投递消息…

聚焦民生服务 助力企业发展 区块链应用加速落地

聚焦民生服务,助力企业发展,区块链应用正在加速落地。这一趋势体现了区块链技术在多个领域的广泛应用和深远影响。以下是对这一主题的详细分析: 一、区块链在民生服务中的应用 政务服务 数据共享与打通:区块链技术利用其分布式账…

Python酷库之旅-第三方库Pandas(048)

目录 一、用法精讲 171、pandas.Series.nlargest方法 171-1、语法 171-2、参数 171-3、功能 171-4、返回值 171-5、说明 171-6、用法 171-6-1、数据准备 171-6-2、代码示例 171-6-3、结果输出 172、pandas.Series.nsmallest方法 172-1、语法 172-2、参数 172-3、…

自动化测试 - selenium 环境搭建

在进行自动化测试时,Selenium 是一个非常强大的工具,在使用前需要做一些环境准备。 1. 配置 Chromedriver 访问 Chrome 浏览器的官方网站(https://www.google.cn/chrome/),下载并安装 Chrome 浏览器。 接下来&#x…

html必知必会-html内嵌JavaScript和文件路径

文章目录 HTML JavaScriptHTML <script> 标签JavaScript 的简单示例HTML <noscript> 标签HTML 文件路径绝对文件路径相对文件路径总结 HTML JavaScript JavaScript 使 HTML 页面更具动态性和交互性。 示例 <!DOCTYPE html> <html> <body><…

自训练和增量训练word2vec模型

1、自己准备训练语料文件 根据自己的业务场景准备训练数据&#xff0c;比如用户在商城上的同购行为序列或同浏览行为序列。 我们希望通过自己训练业务相关的语料word2vec模型来获得词嵌入、词相关性查询等。 1.1 准备语料库文件 # 示例&#xff1a;准备自己的一个大规模的语…

RDMA通信4:MR(Memory Region, 内存区域)基本概念和作用

MR简介 RDMA通信中MR(Memory Region)指的是由RDMA软件层在内存中规划出的一片区域&#xff0c;用于存放收发的数据。IB协议中&#xff0c;用户在申请完用于存放数据的内存区域之后&#xff0c;都需要通过调用IB框架提供的API注册MR&#xff0c;才能让RDMA网卡访问这片内存区域…

2.1、matlab绘图汇总(图例、标题、坐标轴、线条格式、颜色和散点格式设置)

1、前言 在 MATLAB 中进行绘图是一种非常常见且实用的操作&#xff0c;可以用来可视化数据、结果展示、分析趋势等。通过 MATLAB 的绘图功能&#xff0c;用户可以创建各种类型的图形&#xff0c;包括线图、散点图、柱状图、曲线图等&#xff0c;以及三维图形、动画等复杂的可视…

数据中台 | 3分钟带你读懂数据中台的由来

1.数据中台产生的原因 数据中台的概念起源于中国阿里巴巴集团提出的“大中台&#xff0c;小前台”战略。这一理念的核心在于通过构建强大的中台体系&#xff0c;为前端的快速创新和个性化业务需求提供强有力的支持。具体到数据中台&#xff0c;其设计初衷是为了应对企业内部数…

springboot在加了mapper之后报错

springboot在加了mapper之后报错 最后发现是spring boot版本不兼容&#xff0c;spring-boot-starter-parent换成3.0.5之后可以了

计算机基础-IO

一、裸机中的IO 我们先看下计算机的组成部分&#xff1a; 从图中我们很清楚的看到Input/Output 即为 IO&#xff0c;也就是计算机主机和外部设备进行信息的交换。 这种交换可能是磁盘IO也有可能是网络IO。 二、操作系统中的IO 操作系统分为内核态和用户态&#xff0c;且默认…

活动预告|8月3日 Streaming Lakehouse Meetup · Online 与你相约!

随着大数据分析技术的发展&#xff0c;越来越多的企业采用了数据湖架构。基于 Lakehouse 的架构优势&#xff0c;结合 Flink 的 Streaming 实时流处理能力&#xff0c;Flink 推出了新一代的“Streaming Lakehouse”技术。这一技术旨在能够让数据在湖上自由流动&#xff0c;为用…