队列的实现以及队列如何实现栈

一、队列的定义

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出
FIFO(First In First Out) 入队列:进行插入操作的一端称为 队尾 出队列:进行删除操作的一端称为 队头
队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

二、头文件以及结构设计

因为队列对头节点和尾节点使用多,所以我们用一个结构体封装出其头节点和尾节点的地址,会更加方便我们后续的操作:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
// 链式结构:表示队列
typedef int  QDataType;
typedef struct QListNode
{
	struct QListNode* _pNext;
	QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
	QNode* _front;
	QNode* _rear;
	int size;
}Queue;
// 初始化队列
void QueueInit(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 QueueDestroy(Queue* q);

三、.c文件的实现

1、初始化

void QueueInit(Queue* q)
{
	assert(q);
	q->_front = NULL;
	q->_rear = NULL;
	q->size = 0;
}

2、销毁

注意这个与链表的销毁很想,不能简单的只释放Queue节点,而是要通过循环将每一块申请的空间都释放(充分体现了链表的物理结构不连续)

void QueueDestroy(Queue* q)
{
	QNode* tmp = q->_front;
	while (tmp!=NULL)
	{
		QNode* next = tmp->_pNext;
		free(tmp);
		tmp = next;
	}
	q->_front = q->_rear = NULL;
	q->size = 0;
}

 3、插入

void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* tmp = (QNode*)malloc(sizeof(QNode));
	if (tmp == NULL)
	{
		perror("malloc fail");
		return;
	}
	else 
	{
		tmp->_data = data;
		tmp->_pNext = NULL;
	}
	if (q->_rear == NULL)
	{
		q->_front = q->_rear = tmp;
	}
	else
	{
		q->_rear->_pNext = tmp;
		q->_rear = tmp;
	}
	q->size++;
}

4、出列

void QueuePop(Queue* q)
{
	assert(q);
	assert(q->_front);
	assert(q->size != 0);
	if (q->_front->_pNext == NULL)//只有一个节点
	{
		free(q->_front);
		q->_front = q->_rear = NULL;
	}
	else
	{
		QNode* next = q->_front->_pNext;
		free(q->_front->_pNext);
		q->_front = next;
	}
	q->size--;
}

5、访问头数据

QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->_front);
	return q->_front->_data;
}

6、访问尾数据

QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->_rear);
	return q->_rear->_data;
}

7、判断是否为空和获取数据个数

// 获取队列中有效元素个数
int QueueSize(Queue* q)
{
	assert(q);
	return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{
	assert(q);
	return q->size == 0;
}

四、用队列实现栈

1、分析

我们知道栈是先出后进,而队列是先进先出;

为了操作简单,我们在一个队列中存储数据;当我们需要插入时,我们可以直接插入,将队列的队尾当做栈顶,而当我们要出数据时,我们可以将前n个数据移动到第二个队列中,最后一个在原队列中出(此时最后一个数据为第一个数据,符合先进先出);

有了以上的思路,那么这道题就非常容易解决了:

2、实现

这里要注意力扣上关于这个函数

它返回的是一个栈这个与初始化不一样。不能再函数内部直接创建栈变量,而是malloc申请一块空间后返回该指针(因为局部变量出函数就自动销毁了)

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


MyStack* myStackCreate() {
    MyStack*psk=(MyStack*)malloc(sizeof(MyStack));
    QueueInit(&(psk->q1));
    QueueInit(&(psk->q2));
    return psk;
}

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

    }
}

int myStackPop(MyStack* obj) 
{
    Queue* tmp=&(obj->q1);//假设p1为空
    Queue* ntmp=&(obj->q2);//p2不为空
    if(!QueueEmpty(&(obj->q1)))
    {
        tmp=&(obj->q2);
        ntmp=&(obj->q1);//假设p1为空
    }
    while(QueueSize(ntmp)>1)
    {
        QueuePush(tmp,QueueFront(ntmp));
        QueuePop(ntmp);
    }
    int top=QueueFront(ntmp);
    QueuePop(ntmp);
    return top;
}

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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

选型前必看,西门子五大系列PLC的区别及特点

西门子是全球知名的自动化解决方案提供商&#xff0c;其PLC&#xff08;可编程逻辑控制器&#xff09;系列产品广泛应用于工业控制领域。不同系列的PLC在功能、性能和适用范围上有所区别。本文将详细介绍西门子PLC各个系列的特点和区别&#xff0c;以及在实践应用时如何采用无线…

用vsCode开发uni-app(vue + ts)项目流程

提示:记录项目创建流程 文章目录 前言一、安装 uni-app 插件二、ts 类型校验1.安装类型声明文件2.配置 tsconfig,json三、json 注释问题四、组件引入1. 安装 uni-app2. 组件自动引入3. 配置 ts 类型五、小程序端 Pinia 持久化六、uni.request 请求封装七、请求成功提取数据和设…

内容付费小程序功能源码系统 带完整的安装代码包以及搭建部署教程

随着互联网技术的不断进步&#xff0c;内容创作和传播方式发生了翻天覆地的变化。用户对于高质量、有价值的内容需求日益增长&#xff0c;而内容创作者也希望通过自己的专业知识、经验分享等方式获取经济回报。然而&#xff0c;传统的内容分发方式存在诸多局限性&#xff0c;如…

使用map类型的参数在mapper.xml中使用案例

使用map类型的参数在mapper.xml中使用案例 简介&#xff1a;在常见的开发中&#xff0c;对于参数的装载一般使用map类型方式&#xff0c;这样可以避免创建很多参数实体类&#xff0c;不管嵌套多层的数据参数都可以通过map拿取&#xff0c;对于嵌套多层的map&#xff0c;我们需…

事件代理 浅谈

事件代理是一种将事件处理委托给父元素或祖先元素来管理的技术。当子元素触发特定事件时&#xff0c;该事件不会直接在子元素上进行处理&#xff0c;而是会冒泡到父元素或祖先元素&#xff0c;并在那里进行处理。这样做的好处是可以减少事件处理函数的数量&#xff0c;提高性能…

Centos 7.9 安装 tigervnc-server

环境&#xff1a;当前使用的 Centos 7.9 的光盘作为的本地源。 1 检查是否已安装 tigervnc [rootlocalhost /]# rpm -q tigervnc tigervnc-server 未安装软件包 tigervnc tigervnc-server-1.8.0-21.el7.x86_64 如果安装过卸掉 卸载: rpm -e [rootlocalhost /]# rpm -e tige…

Springboot 集成 Consul 实现服务注册中心-05

因为后续很多模块都要用到注册中心&#xff0c;所以此处先实现此模块。 Consul简介 Consul是一个开源的服务发现和配置管理工具&#xff0c;具有跨平台、运行高效等特点。它由HashiCorp公司开发&#xff0c;并使用Go语言编写。Consul主要用于实现分布式系统中的服务发现、健康…

代码随想录Day 41|Leetcode|Python|198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

198.打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个…

搭建私有仓库Nexus的流程以及npm包的开发和发布

搭建私有仓库 Nexus 的流程&#xff08;Ubuntu&#xff09;以及 npm 包的开发和发布 本文档是关于在 Ubuntu 上面搭建 Nexus&#xff0c;以及制作 npm 包并发布到 Nexus 的流程说明。 关于 Ubuntu Ubuntu 是一个基于 Linux 的操作系统&#xff0c;通常会用在服务器或者嵌入式…

luceda ipkiss教程 71:统计线路中器件的个数

**案例分享&#xff1a;**统计线路中某一器件的个数 如&#xff0c;统计SplitterTree中mmi的个数&#xff1a; 所有代码如下&#xff1a; # Copyright (C) 2020 Luceda Photonicsfrom si_fab import all as pdk from ipkiss3 import all as i3class GeneralizedSplitterTree…

手机恢复出厂设置会怎么样?一切回到了原点?

随着智能手机的普及&#xff0c;我们每天都在与手机紧密互动&#xff0c;里边存储了大量的个人信息和应用数据。然而&#xff0c;有时候我们会遇到手机卡顿、应用崩溃或数据丢失的问题。这时&#xff0c;恢复出厂设置成为了许多人的选择。那么&#xff0c;手机恢复出厂设置会怎…

专项技能训练五《云计算网络技术与应用》实训8-1:建立基于OpenvSwitch的GRE隧道

文章目录 建立基于OpenvSwitch的GRE隧道1. 使用VMware安装2个CentOS 7虚拟机&#xff0c;安装时记得都开启CPU虚拟化&#xff0c;第一台命名为“Docker”&#xff0c;第二台命名为“KVM”。2. 安装完虚拟机后&#xff0c;进入虚拟机&#xff0c;修改网络配置&#xff08;onboot…

数据序列包分析

基于数据序列包分析各部分的内容及含义&#xff0c;可能会考大题 基于本例分析&#xff0c;每部分含义如下&#xff1a; 时间&#xff08;Time&#xff09;&#xff1a; 时间戳显示了数据包在网络中被捕获的具体时间。在本例中&#xff0c;如"0.000000"表示第一个数据…

Golang | Leetcode Golang题解之第75题颜色分类

题目&#xff1a; 题解&#xff1a; func sortColors(nums []int) {p0, p2 : 0, len(nums)-1for i : 0; i < p2; i {for ; i < p2 && nums[i] 2; p2-- {nums[i], nums[p2] nums[p2], nums[i]}if nums[i] 0 {nums[i], nums[p0] nums[p0], nums[i]p0}} }

共用nacos造成的开发问题记录

目录 1.需求提出 2.系统架构 3.问题抛出 4.解决办法 1.配置私有命名空间 2.给服务加后缀 1.需求提出 本地调试用到哪个服务启动哪个服务&#xff0c;其他支持服务调用测试环境上的&#xff0c;目的是避免本地启动多个服务&#xff0c;消耗电脑配置。 2.系统架构 项目是…

im(即时通讯)是什么?

在当今数字化时代&#xff0c;即时通讯&#xff08;IM&#xff09;已经成为企业内部沟通与协作中不可或缺的工具。作为一种实时的即时通讯方式&#xff0c;IM能够极大提高团队成员之间的沟通效率&#xff0c;帮助企业快速响应变化&#xff0c;并增强内部协作与创新能力。 Work…

猫不仅吃猫粮,还可以吃这种食物,这些主食冻干喵吃了会开心哦

随着科学养猫的普及&#xff0c;主食冻干喂养越来越受欢迎&#xff0c;主食冻干喂养对猫的好处很多&#xff0c;它符合猫咪的天性&#xff0c;可以提供全面的营养&#xff0c;保持牙齿和牙龈的健康&#xff0c;还有助于维持健康的消化系统。所以铲屎官们不要在局限只给猫咪喂猫…

无需设置环境变量,Linux下最正确的Java离线安装方式

背景 公司研发网络是离线环境&#xff0c;需要安装Java环境&#xff0c;网上教程大多是在线安装或者通过设置环境变量安装&#xff0c;设置环境变量的方式是最常见的&#xff0c;但确隐藏了很多坑&#xff0c;例如环境变量有时候会不生效&#xff0c;如果你的程序通过systemd启…

6 7 8 9 11 12 15 17 18 20 22cm散热风扇防护网风扇金属网罩

品牌&#xff1a;威驰 颜色分类&#xff1a;60mm/6cm金属网,80mm/8cm金属网,92mm/9.2cm金属网,110mm/11cm金属网,120mm/12cm金属网,150mm/15cm金属网,172mm/17.2cm金属网,200mm/20cm金属网,280mm/28cm金属网 1产品参数&#xff0c;防护网罩60 80 90 110 120 125 145 150 180…

46.乐理基础-音符的组合方式-延音线

以四分音符为一拍的时候想要某个音符的时长为1.25拍的时候&#xff0c;没法表示出来&#xff0c;使用普通的音符、加了附点、或复附点的音符就是没办法表示出1.25拍。 最后一种组合音符拍号的记号&#xff0c;延音线&#xff0c;如下图&#xff0c;以四分音符为一拍&#xff0…