队列的实现及其应用

news2024/10/5 14:16:41

队列的概念

        队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作,具有先进先出的效果。入数据的一段称为队尾,出数据的一段称为队头。队列的应用是:1.维持公平性(抽号)、2.广度优先遍历。

队列的应用

1.抽号

        先排队的人先入队列,这样可以保证先进先出,从而保证公平性

2.广度优先遍历(好友推荐算法)

        

        将用户的好友入队列,在知道用户好友数量的前提下,将好友出队列。

队列的实现

        如果要想实现队列,我们发现数组无法实现,原因是每次出入队列都要进行数据的挪动,这样会消耗很多空间,故我们用链表实现。

1.队列创建及目录

typedef int QDataType;

typedef struct QueneNode
{
	struct QueneNode* next;
	QDataType val;
}QNode;

typedef struct Quene//避免用到二级指针与多指针,将其封装到结构体里
{
	QNode* phead;
	QNode* ptail;
	QDataType size;
}Queue;

//初始化
void QueueInit(Queue* pq);
//入队列
void QueuePush(Queue* pq, QDataType x);
//出队列
void QueuePop(Queue* pq);
//求数据个数
int QueueSize(Queue* pq);
//取队头数据
QDataType QueueFront(Queue* pq);
//取队头数据
QDataType QueueBack(Queue* pq);
//判空
bool QueueEmpty(Queue* pq);
//队列的销毁
void QueueDestroy(Queue* pq);

        在这里,我们为了防止函数中创建二级指针,于是选择再单独创建一个结构体Quene来存放一级指针;除此之外,在传递指针时我们也可以只传递一个结构体变量。

2.队列的初始化

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

3.入队列

        我们仍然选择在入队列时创建新节点,最后一定不要忘了size++.

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloce fail!");
		return;
	}
	newnode->next = NULL;
	newnode->val = x;

	if (pq->ptail == NULL)
	{
		pq->ptail = pq->phead = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

4.出队列

        在出队列函数中,我们要注意节点为0和节点为1时要单独进行考虑。

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->size != 0);//0个节点
	if (pq->phead->next == NULL)//一个节点
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else//多个节点
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;//队列减少直接size--即可
}

5.求数据个数

int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

        由于我们在创建结构体时已经为size单独创建了一个变量size,所以这里只需将其返回即可.

6.取队头数据

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->phead);
}
	

        取队头数据时就要注意对队头判空.

7.取队尾数据

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->ptail);

	return pq->ptail->val;
}

        取队尾数据仍然不要忘记对队尾判空

8.队列判空

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->size == 0;
}

        如果pq的size等于0,则返回true,否则返回false.

9.队列的销毁

void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
        //先释放,再移动cur从而实现队列的销毁
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

10.队列的打印

        与栈类似,如果我们要打印队列,同样是要每打印一个数,就要对其进行一次删除操作,代码如下:

int main()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QuenuePush(&q, 4);

	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");
	return 0;
}

队列的应用

用队列实现栈

       在这里我们用两个队列实现栈,保持一个存数据,一个为空,入数据入不为空的队列,出数据就通过空队列.

通过结构体创建两队列

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

栈的初始化

对于栈的初始化,我们首先仍然要创建内存(malloc).

然后对q1q2分别初始化:

MyStack* myStackCreate() //初始化Init
{
    MyStack* obj = (MyStack*)malloc(sizeof(MyStack));//malloc了内存可以一直存在
    QueueInit(&obj->q1);
    QueueInit(&obj->q2);

    return obj;
}

栈的插入

由于队列的特点是先进后出,所以对于栈的插入来说可以直接将q1q2里的值插入即可。要记得判空。

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

栈的删除

对于代码的if else语句,我们还可以用假设法对其进行优化,假设q1为空,q2不为空,然后将队列中的元素导走。

int myStackPop(MyStack* obj) {
    //假设法
    Queue* empty = &(obj->q1);
    //不为空的前size-1个导走
    Queue* nonempty = &(obj->q2);
    if(!QueueEmpty(&obj->q1))
    {
        nonempty = &obj->q1;
        empty = &obj->q2;
    }
    while(QueueSize(nonempty) > 1)
    {
        QueuePush(empty,QueueFront(nonempty));
        QueuePop(nonempty);
    }
    int top = QueueFront(nonempty);
    QueuePop(nonempty);
    return top;
}

取栈顶元素

若要取栈顶元素,则直接将队列尾return 即可

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

栈的释放

对于栈的释放,要先对两队列依次进行释放,再将obj直接释放

void myStackFree(MyStack* obj) {
    //不能直接释放obj
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
}

        如果觉得我写的不错,别忘了点赞收藏+评论!

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

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

相关文章

JVM垃圾收集器和性能调优

目标: 1.JVM垃圾收集器有哪几种? 2.CMS垃圾收集器回收步骤。 一、JVM常见的垃圾回收器 为什么垃圾回收的时候需要STW? 标记垃圾的时候,如果不STW,可能用户线程就会不停的产生垃圾。 1.1 单线程收集 Serial和SerialOld使用单…

大语言模型应用与传统程序的不同

大语言模型(LLM) 被描述的神乎其神,无所不能,其实,大语言模型只是一个模型,它能够理解和生成自然语言,唯有依靠应用程序才能够发挥作用。例如,基于大模型可以构建一个最简单的会话机…

黑马python-JavaScript

1.JavaScript的定义&#xff1a; JavaScript是运行在浏览器端的脚步语言&#xff0c;是由浏览器解释执行的、简称js。它能够让网页和用户有交互功能&#xff0c;增加良好的用户体验效果 2.使用方式&#xff1a; 1.行内式&#xff08;主要用于事件&#xff09; <input type&q…

24-unittest简介

一、unittest简介 unittest是Python中常用的单元测试框架&#xff0c;与Java中的Junit单元测试框架类似。 二、示例程序 1&#xff09;导入unittest模块 import unittest 2&#xff09;使用help()函数查看源码中的示例程序 help(unittest) Simple usage:import unittestc…

Unity DOTS技术(二)ECS

文章目录 一.ECS简介二.基本操作实例三.实体查看组件四.位置实体修改五.旋转实体六.了解原有属性七.禁止自动创建八.动态实例化 一.ECS简介 ECS全称 (Entity Component System).即(E:实体 C:组件 S:系统). 实际上即是数据方法分离.数据放在组件里,具体实现放在系统里.组件挂载…

【excel】设置二级可变联动菜单

文章目录 【需求】在一级菜单选定后&#xff0c;二级菜单联动显示一级菜单下的可选项【步骤】step1 制作辅助列1.列转行2.在辅助列中匹配班级成员 step2 名称管理器step3 制作二级下拉菜单step4 消除二级菜单中的空白 【总结】 之前做完了 【excel】设置可变下拉菜单&#xff…

NPDP|智造业产品经理的战略智慧与行动之道

在智能制造风起云涌的时代&#xff0c;智造业产品经理的角色愈发重要。他们不仅需要具备深厚的行业知识&#xff0c;更要拥有前瞻的战略眼光和高效的行动能力。那么&#xff0c;智造业产品经理如何进行战略思考与行动呢&#xff1f;本文将为您揭示其中的奥秘。 洞察市场趋势&am…

01_初识微服务

文章目录 一、微服务概述1.1 什么是微服务1.2 对比微服务架构与单体架构1.3 微服务设计原则1.4 微服务开发框架1.5 简单理解分布式部署与集群部署 二、微服务的核心概念2.1 服务注册与发现2.2 微服调用&#xff08;通信&#xff09;2.3 服务网关2.4 服务容错2.5 链路追踪参考链…

用友NC pagesServlet SQL注入致RCE漏洞复现(XVE-2024-13067)

0x01 产品简介 用友NC是由用友公司开发的一套面向大型企业和集团型企业的管理软件产品系列。这一系列产品基于全球最新的互联网技术、云计算技术和移动应用技术,旨在帮助企业创新管理模式、引领商业变革。 0x02 漏洞概述 用友NC /portal/pt/servlet/pagesServlet/doPost接口…

焦化超低排平台改造指南

在当今社会&#xff0c;环保已成为各行各业的共识&#xff0c;焦化行业也不例外。随着环保政策的日益严格&#xff0c;焦化超低排平台改造成为了行业内的热点话题。本文旨在为广大焦化企业提供一份全面、实用的改造指南&#xff0c;帮助企业顺利实现超低排放&#xff0c;迈向绿…

python 字符串(str)、列表(list)、元组(tuple)、字典(dict)

学习目标: 1:能够知道如何定义一个字符串; [重点] 使用双引号引起来: 变量名 "xxxx" 2:能够知道切片的语法格式; [重点] [起始: 结束] 3:掌握如何定义一个列表; [重点] 使用[ ]引起来: 变量名 [xx,xx,...] 4:能够说出4个列表相关的方法; [了解] ap…

解决在Windows11上新安装的Docker Desktop一直显示“starting the Docker Engine“登录不上去的问题

解决在Windows11上新安装的Docker Desktop一直显示“starting the Docker Engine“登录不上去的问题 管理员权限运行cmd 还需要安装wsl(适用于Linux的Windows子系统)。注意windows powershell也要以管理员权限打开 这个是小羊用错窗口了&#xff0c;but好像也没错吧&#xff…

shell的编程方式

文章目录 变量俩种方式第一种方式第二种方式 取消变量数组创建数组获取数组元素的方式 read输出的方式限制输入的方式 流程控制方式for循环输出的方式第一种方式第二种方式while循环输出的方式select选择输出的方式 判断方式判断的四种方式第一种方式第二种方式第三种方式 算术…

C++之RTTI

1、RTTI&#xff08;runtime type information&#xff09;运行时类型信息 static_cast&#xff1a;用在编译器认可的转型 reinterpret_cast&#xff1a;用在编译器不认可的转型&#xff08;不做任何的对齐操作&#xff09; const_cast&#xff1a;去除常量属性 dynamic_ca…

国产开发板——香橙派Kunpeng Pro的上手初体验

开发板&#xff08;Development Board&#xff09;是一种特殊的电子产品&#xff0c;它的主要目的是为了帮助开发者快速地设计、测试和验证电子产品的硬件和软件设计。开发板通常提供了一个完整的硬件平台&#xff0c;包括微控制器、存储器、接口和其他外围设备&#xff0c;开发…

开源Mamba-2性能狂飙8倍!多个Mamba超强进化体拿下顶会

MambaOut的热度刚过去没多久&#xff0c;Mamba-2就带着它狂飙8倍的性能炸场了。 Mamba-2的核心层是对Mamba的选择性SSM的改进&#xff0c;同等性能下&#xff0c;模型更小&#xff0c;消耗更低&#xff0c;速度更快。与Mamba不同&#xff0c;新一代的Mamba-2再战顶会&#xff…

机器人舵机:关键要素解析与选择指南

在机器人技术日新月异的今天&#xff0c;舵机作为机器人的核心部件之一&#xff0c;扮演着至关重要的角色。它的性能直接关系到机器人的运动控制、稳定性以及精度等方面。那么&#xff0c;在选择和使用机器人舵机时&#xff0c;我们需要关注哪些关键要素呢&#xff1f;本文将为…

网络协议二

一、套接字Socket 基于 TCP UDP 协议的 Socket 编程&#xff0c;在讲 TCP 和 UDP 协议的时候&#xff0c;我们分客户端和服务端&#xff0c;在写程序的时候&#xff0c;我们也同样这样分。 在网络层&#xff0c;Socket 函数需要指定到底是 IPv4 还是 IPv6&#xff0c;分别对应设…

【数据集划分】oracle数据集划分(总结版)

【数据集划分】假如你有接近百万条oracle数据库数据&#xff08;成真版&#xff09; 写在最前面最终代码原理&#xff1a;生成随机索引并打乱顺序示例作用应用场景 遇到报错&#xff1a;ORA-01795&#xff0c;通过CTE&#xff08;Common Table Expressions&#xff09;和窗口函…

springcloud Feign调用拦截器(统一处理拷贝请求头实现透传信息、内部调用鉴权、打印feign调用)

springcloud Feign调用拦截器&#xff08;统一处理拷贝请求头实现透传信息、内部调用鉴权、打印feign调用日志&#xff09; 实现接口Feign.RequestInterceptor 实现接口 feign.RequestInterceptor 并注入到IOC容器即可生效 示范代码如下 拷贝请求头&#xff0c;将原请求信…