【队列】循环队列(Circular Queue)详解

【队列】循环队列(Circular Queue)详解

文章目录

一、循环队列简介

在实际开发中,队列是一种常用的数据结构,而循环队列(Circular Queue)则一般是一种基于数组实现的队列(也可使用循环链表)。与传统的 FIFO 队列相比,循环队列通过将数组首尾相连形成一个 “环”,能够更高效地利用内存空间。

循环队列的主要思想是:当队尾指针到达数组末端时,如果数组前面还有空余空间,就可以从数组头部重新利用这些空间进行入队操作。也就是说,数组的末端和头部通过逻辑上的连接,形成一个环状结构,从而避免了顺序队列中由于出队操作而导致的空间浪费问题。

如下图就是一个典型的循环队列,其中的 front 表示头指针,指向队头。rear 则表示尾指针,指向队尾元素的下一个位置。

请添加图片描述

二、循环队列的判空和判满

在循环队列中,frontrear 都是可以循环移动的,当队空时,front == rear 成立;当队满时,front == rear 也成立。因此显然不能只凭 front == rear 来判断队空还是队满。

为了解决这个问题,在循环队列中约定:少用一个元素空间,当队尾标识的 rear在队头标识front 的上一个位置时,队列为满。此时,判断队空和队满的条件分别如下:

队空时:front == rear

队满时:(rear + 1) % MAXSIZE == front

其中,MAXSIZE 是队列容量的大小

两种情况下队列中指针的状态如下图所示:

请添加图片描述

既然少一个元素空间,这就意味着,如果要存储的数据个数最大为 k,那么你需要开辟的循环队列的大小应为 k+1

三、循环队列的实现

我们来以具体的一道题目来实现循环队列的各种操作

leetcode 622. 设计循环队列

typedefstruct{int* a;int front;// 头“指针”指向队头数据int tail;// 尾“指针”指向队尾的下一个位置int k;// 一会儿开辟的队列大小为 k+1} MyCircularQueue; bool myCircularQueueIsEmpty(MyCircularQueue* obj); bool myCircularQueueIsFull(MyCircularQueue* obj);// 前面先实现的函数要用到这两个接口,所以事先声明一下// 循环队列的初始化 MyCircularQueue*myCircularQueueCreate(int k){ MyCircularQueue* cq =(MyCircularQueue*)malloc(sizeof(MyCircularQueue)); cq->a =(int*)malloc(sizeof(int)*(k+1)); cq->front =0;// 初始化数据 cq->tail =0; cq->k = k;return cq;}// 入队 bool myCircularQueueEnQueue(MyCircularQueue* obj,int value){if(myCircularQueueIsFull(obj))return false;// 满了就不能再入了 obj->a[obj->tail]= value;// 将数据入进来++obj->tail;// 更新tail obj->tail %=(obj->k+1);// tail 自增了之后可能超出循环队列的大小范围所以要取模// 模的是循环队列的大小 k+1return true;}// 出队 bool myCircularQueueDeQueue(MyCircularQueue* obj){if(myCircularQueueIsEmpty(obj))return false;// 为空就不能再删 obj->front =(obj->front+1)%(obj->k+1);// 和前面是一样的原理,注意同样是加一再取模return true;}// 获取队头元素intmyCircularQueueFront(MyCircularQueue* obj){if(myCircularQueueIsEmpty(obj))return-1;return obj->a[obj->front];}// 获取队尾元素intmyCircularQueueRear(MyCircularQueue* obj){if(myCircularQueueIsEmpty(obj))return-1;if(obj->tail ==0)return obj->a[obj->k];// 跨越了一个循环的情况elsereturn obj->a[obj->tail-1];}// 判空 bool myCircularQueueIsEmpty(MyCircularQueue* obj){return obj->front == obj->tail;}// 判满 bool myCircularQueueIsFull(MyCircularQueue* obj){return(obj->tail+1)%(obj->k+1)== obj->front;// tail的后一个是front说明满了,但是有可能tail+1跨过了一个循环。所以要取模}// 释放voidmyCircularQueueFree(MyCircularQueue* obj){free(obj->a);// 注意这里要先释放结构体内的数组!!!不然会可能内存泄漏free(obj);}

Read more

基于LangGraph实现模块化Skills型AI Agent

基于LangGraph+DeepSeek+Serper 实现模块化Skills型AI Agent 在AI Agent的落地实践中,模块化Skills设计是提升Agent可扩展性、可维护性的核心方案——将搜索、计算、文件处理等能力封装为独立Skills,Agent可根据需求自主调用,无需修改核心流程。本文将基于LangGraph、DeepSeek大模型和Serper搜索工具,手把手带你实现一个具备工具调用能力的Skills型AI Agent,同时解决开发中常见的MRO冲突、Pydantic验证等问题,代码可直接复制运行。 一、前言:为什么选择Skills型Agent? 传统AI Agent多采用「硬编码工具调用」的方式,新增能力需修改核心逻辑,耦合度高且难以维护。而Skills型Agent将能力拆分为独立的Skill模块,每个Skill遵循统一接口,具备以下优势: 1. 模块化解耦:新增/修改Skill无需改动Agent核心流程,即插即用; 2. 智能决策:大模型自主判断是否调用Skill、调用哪个Skill,无需人工干预; 3. 可扩展性强:支持搜索、计算、代码解释、数

SpringAI 大模型应用开发篇-SpringAI 项目的新手入门知识

SpringAI 大模型应用开发篇-SpringAI 项目的新手入门知识

🔥博客主页: 【小扳_-ZEEKLOG博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录         1.0 SpringAI 概述         1.1 大模型的使用         2.0 SpringAI 新手入门         2.1 配置 pom.xml 文件         2.2 配置 application.yaml 文件         2.3 配置 ChatClient         2.4 同步调用         2.5 流式调用         2.6 System 设定         2.7 日志功能         2.8 会话记忆功能

构建基于Go语言的高性能命令行AI对话客户端:从环境部署到核心实现

构建基于Go语言的高性能命令行AI对话客户端:从环境部署到核心实现

前言 在现代软件开发领域,Go语言凭借其卓越的并发处理能力、静态类型安全以及高效的编译速度,已成为构建命令行工具(CLI)的首选语言之一。本文将详细阐述如何在Ubuntu Linux环境下部署Go开发环境,并结合蓝耘(Lanyun)提供的DeepSeek大模型API,手写一个支持多轮对话、上下文记忆的智能终端聊天工具。 一、 基础运行环境的准备与构建 任何上层应用的稳健运行都离不开坚实的底层系统支持。本次部署的目标环境为Ubuntu LTS系列(20.04/22.04/24.04),这些长期支持版本保证了系统库的稳定性与安全性。硬件层面,建议配置至少1GB的内存与5GB的磁盘空间,以满足编译器运行及依赖包缓存的需求。 1. 系统包索引更新与系统升级 在进行任何开发工具安装之前,首要任务是确保操作系统的软件包索引与现有软件处于最新状态。这不仅能修复已知的安全漏洞,还能避免因依赖库版本过旧导致的编译错误。 执行系统更新操作: sudoapt update &&sudoapt upgrade -y 该指令分为两部分:apt update 用于从软件源服务器获取最新的软件包列

别被“会聊天”的AI骗了!真正的数字助理,应该是ToClaw这样的

别被“会聊天”的AI骗了!真正的数字助理,应该是ToClaw这样的

这段时间 OpenClaw 很火,火到不少人第一次开始认真讨论一件事: AI 到底该只是陪你聊天,还是应该替你把事完成? 从官方说明看,OpenClaw 更偏向个人开源 AI 助手路线,推荐通过终端里的 onboarding wizard 完成配置,Windows 侧也建议走 WSL2。这种路线很酷,但对大多数普通办公用户来说,还是意味着一定的学习和折腾成本。 也正因为这样,我反而更能理解 ToDesk 推出 ToClaw 的价值:它不是想让每个人都去研究怎么“部署一个龙虾”,而是想把 AI 直接变成一个你登录 ToDesk 后就能随时使唤的数字助理。 真正的差别,不是会不会聊天,而是会不会接任务 现在很多 AI 工具都已经“很会说”了。写总结、写标题、润色文案、翻译内容,基本都不难。但问题在于,真实工作并不是一个纯聊天场景。