队列问题非STL解决方案
队列问题非STL解决方案
常年使用STL解决队列问题,以至于严重生疏队列的根本原理。。。
直到今日 被老师被迫 使用算法原理解决问题,方才意识到我对队列一窍不通。。。
。。。直到 经过一系列的坑蒙拐骗 之后,方才理清楚一些头绪,在此附记。
有关概念在此不再赘述,因为这东西怕不是一搜一大堆。。。
循环队列——数组存储方案:
我们需要的东西:
1.一个数组,拿来存队列。
int ique[capa];//capa是数组(队列)的最大容量,看下面↓
2.头指针及尾指针,指明队列的头和尾。
int ihead=0,itail=0;
3.再来两个量——队列的当前长度(是变量)及其最大容量(是常量,在开数组时已经界定,这里为演示开的短一些,只开到4)
int ilen=0;
const int capa=4;
接下来是一些基本的操作:
1.将elem入队:
int elem;
ique[itail]=elem;//尾指针始终指向队列尾部的下一个位置,因此我们只需将尾指针处的数字做出更改即可。
itail++;//尾指针自增,指向下一个位置。
itail=itail % capa;//圈重点,见下↓
ilen++;//因为多了一个元素而长度增加,使ilen自增。
itail=itail % capa;
我们一直在使尾指针自增,而数组的长度只有4。 在这里通过取余即可实现循环入队。这样当尾指针增大到capa以外时,通过该语句即可自动使尾指针跳转回数组的开头,实现循环读入、循环存储。
在这里尾指针始终指向队列尾部的下一个位置,使其指向队列尾部那个元素的原理是相同的。
2.出队,存入elem:
int elem;
elem=ique[ihead];//直接取出头指针处的元素
ihead++;//头指针往下移动
ihead=ihead % capa;//和上面同理
ilen--;//因为少了一个元素而长度减少,使ilen自减。
比较关键的操作就在于将指针对capa取余,这样的操作可以使指针形成循环,也就实现了队列的循环存储。在其他地方如果我们需要用到循环存储,对其容量取余是个很好的思路。当然实际应用中其大小不仅仅是4这么少,我们还应该留意数据范围合理安排空间,要不出现了塞不下或者空太多的问题都是很辣手棘手的。
基本的操作就是这样 (是不是很简单) (是不是理解起来有些难) (还是本来就挺简单被我给说难了。。。)
举个例子:
洛谷P1996 约瑟夫问题
题目:
n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,……依次类推,直到所有的人都出圈,请输出依次出圈人的编号.
输入格式
n m
输出格式
出圈的编号
输入样例
10 3
输出样例
3 6 9 2 7 1 8 5 10 4
说明
m,n≤100
-->用STL的话基本不用动脑,5分钟搞定。如下:
#include<queue>//队列所必须的头文件
#include<cstdio>
using namespace std;
queue <int> set;//创建该队列
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
set.push(i);//把各个人的编号入队准备报数
}
int counti=1;//报数的计数器
while(!set.empty())
{
if(counti!=m)
{
set.push(set.front());//不是m,循环将队头塞进队尾,实现循环
set.pop();
}
if(counti==m)
{
printf("%d ",set.front());//是m这个人出列,将其编号输出后出队
set.pop();
counti=1;//再次从1开始
continue;//继续
}
counti++;
}
return 0;
}
不使用STL的话,构建队列就要稍微麻烦一些,不过能更好的理解其原理及应用。然而无论如何STL都只是个工具,我们必要应该掌握的还是其实现原理。下面是无STL的解决方案:
//luogu.org P1996 -- NO STL Solution
//queue--Array Solution
//IZWB003-2019/07/24
#include<cstdio>
//set queue//设置该队列
int head=0,tail=0;//指针2个
int length=0;const int capacity=120;//大小及长度
int queue[capacity];//通过数组储存队列
int element;
using namespace std;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
queue[tail]=i+1;//尾指针处入队
tail++;
tail=tail%capacity;//上面的方法
length++;//改长度
}
int i=0;//以i作为报数的计数器
while(true)
{
element=queue[head];//头指针处出队
head++;
head=head%capacity;//上面的方法
length--;//改长度
i++;//报数
if(i==m)//该出队处
{
printf("%d ",element);//输出
i=0;//重新报数
}
else//不符合则接着入队
{
queue[tail]=element;
tail++;
tail=tail%capacity;
length++;
}
if(length==0) break;//队空则结束
}
return 0;
}
有关链表建队列的相关知识,有时间的话,稍后补充。
队列问题非STL解决方案的更多相关文章
- 标准非STL容器 : bitset
1. 概念 什么是"标准非STL容器"?标准非STL容器是指"可以认为它们是容器,但是他们并不满足STL容器的所有要求".前文提到的容器适配器stack.que ...
- 探讨SQL Server并发处理队列数据不阻塞解决方案
前言 之前对于并发这一块确实接触的比较少,自从遇到现在的老大,每写完一块老大都会过目一下然后给出意见,期间确实收获不少,接下来有几篇会来讲解SQL Server中关于并发这一块的内容,有的是总结,有的 ...
- java阻塞队列与非阻塞队列
在并发编程中,有时候需要使用线程安全的队列.如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法. //使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入 ...
- 蓝桥 ADV-233 算法提高 队列操作 【STL】
算法提高 队列操作 时间限制:1.0s 内存限制:256.0MB 问题描述 队列操作题.根据输入的操作命令,操作队列(1)入队.(2)出队并输出.(3)计算队中元素个数并输出. ...
- Windows消息理解(系统消息队列,进程消息队列,非队列消息)
// ====================Windows消息分类==========================在Windows中,消息分为以下三类:标准消息——除WM_COMMAND之外,所 ...
- HDU 4280Island Transport(Dinc非STL 模板)
题意: n岛m条路,然后是 n个岛的坐标,然后是m条双向路,包括 岛和 岛 之间 最大客流量,让求 最左边的岛 到右边的岛 最大客流量 分析: 建图 以 左边的岛为原点,最右边的为终点求最大客流量. ...
- calc 多项式计算 (STL版和非STL版) -SilverN
计算(calc.cpp) [问题描述] 小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*” ...
- 栈和队列简单的STL模板
栈的使用,可以想象成是只有一个出口,最后进来的那个最先出去: #include <stack> 队列:是有两个出口,但是进来了之后只能从前门出去,也就是最先进来的那个最后出去: #incl ...
- win10每次开机都会自检系统盘(非硬件故障)——解决方案2019.07.12
1.最近反复遇到了这个问题,之前遇到这个问题就把系统重装了,没想到今天又遇到了,目前系统东西太多了,重装太麻烦了,就下决心解决一下. 2.不要使用网络上流传的修改注册表的方案,把注册表的那个键值删除那 ...
随机推荐
- 中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结
中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结 标签:数学方法--数论 阅读体验:https://zybuluo.com/Junlier/note/1300035 前置浅讲 前 ...
- MicroPython 的优势
定位的场景 MicroPython 在设计上最初就是为了嵌入式微处理器运行,例如在 nRF51822 (256kB flash + 16kB RAM) 的芯片上也可以运行起来,也有人肾得慌在 STM3 ...
- Version Controlling with Git in Visual Studio Code and Azure DevOps
Overview Azure DevOps supports two types of version control, Git and Team Foundation Version Control ...
- HTML5中的Web Worker
什么是 Web Worker? 当在 HTML 页面中执行脚本时,页面是不可响应的,直到脚本已完成. Web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能.您 ...
- HTML导航框架实现
导航栏界面(html_contents.html) <!DOCTYPE html> <html> <head> <meta charset=” utf-8” ...
- 【知识强化】第七章 输入/输出系统 7.3 I/O接口
下面我们进入第七章的第三节,I/O接口. I/O接口呢就是解决了外设和主机之间的一个连接的问题.那么我们这一节就要来看一下I/O接口它有哪些功能,以及它是怎么组成的,还有就是我们主机如何来定位到那样一 ...
- Centos7 配置rsyslog客户端接收远程日志
rsyslog 因为路由器我设定每天重启,但是日志一重启就会清除,并且路由器最多只能保存1024条记录,所以我想把路由器的日志记录到一台服务器上,发现路由器包含远程日志功能 于是我就在我的centos ...
- JSP学习(5)
JSP学习(5) 保存用户状态的两大机制 session对象 Cookie Cookie简介 是Web服务器保存在客户端的一系列文本信息 典型应用 判断注册用户是否已经登录 购物车处理 作用 对特定对 ...
- linux NFS 的安装准备
关闭 iptables 和 selinux [root@allentuns ~]# service iptables stop [root@allentuns ~]# chkconfig iptabl ...
- apache重写规则简单理解
1.前提:开启apache重写,并把httpd.conf里的相关的AllowOverride denied改为AllowOverride all 2.重写规则可写在项目根目录的.htaccess文件或 ...