队列问题非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解决方案的更多相关文章

  1. 标准非STL容器 : bitset

    1. 概念 什么是"标准非STL容器"?标准非STL容器是指"可以认为它们是容器,但是他们并不满足STL容器的所有要求".前文提到的容器适配器stack.que ...

  2. 探讨SQL Server并发处理队列数据不阻塞解决方案

    前言 之前对于并发这一块确实接触的比较少,自从遇到现在的老大,每写完一块老大都会过目一下然后给出意见,期间确实收获不少,接下来有几篇会来讲解SQL Server中关于并发这一块的内容,有的是总结,有的 ...

  3. java阻塞队列与非阻塞队列

    在并发编程中,有时候需要使用线程安全的队列.如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法. //使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入 ...

  4. 蓝桥 ADV-233 算法提高 队列操作 【STL】

      算法提高 队列操作   时间限制:1.0s   内存限制:256.0MB      问题描述 队列操作题.根据输入的操作命令,操作队列(1)入队.(2)出队并输出.(3)计算队中元素个数并输出. ...

  5. Windows消息理解(系统消息队列,进程消息队列,非队列消息)

    // ====================Windows消息分类==========================在Windows中,消息分为以下三类:标准消息——除WM_COMMAND之外,所 ...

  6. HDU 4280Island Transport(Dinc非STL 模板)

    题意: n岛m条路,然后是 n个岛的坐标,然后是m条双向路,包括 岛和 岛 之间 最大客流量,让求 最左边的岛 到右边的岛 最大客流量 分析: 建图 以 左边的岛为原点,最右边的为终点求最大客流量. ...

  7. calc 多项式计算 (STL版和非STL版) -SilverN

    计算(calc.cpp) [问题描述] 小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*” ...

  8. 栈和队列简单的STL模板

    栈的使用,可以想象成是只有一个出口,最后进来的那个最先出去: #include <stack> 队列:是有两个出口,但是进来了之后只能从前门出去,也就是最先进来的那个最后出去: #incl ...

  9. win10每次开机都会自检系统盘(非硬件故障)——解决方案2019.07.12

    1.最近反复遇到了这个问题,之前遇到这个问题就把系统重装了,没想到今天又遇到了,目前系统东西太多了,重装太麻烦了,就下决心解决一下. 2.不要使用网络上流传的修改注册表的方案,把注册表的那个键值删除那 ...

随机推荐

  1. [2019杭电多校第三场][hdu6606]Distribution of books(线段树&&dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6606 题意为在n个数中选m(自选)个数,然后把m个数分成k块,使得每块数字之和最大的最小. 求数字和最 ...

  2. Kotlin学习(2)函数

    函数声明: fun plus(a:Int,b:String):Boolean{ //fun 函数名(参数名:参数类型,参数名:参数类型):返回值类型 println(a) return true // ...

  3. 一些WinAPI 处理 字符的函数和连接(GetACP和SetThreadLocale最重要,还有SetConsoleCP)

    虽然东西都是现成的.但是也要脑子里有个概念. // 地区与语言GetACP 取得 ANSI code page,法语XP+设置中文内核 = 936 // ShowMessage(IntToStr(Ge ...

  4. IIS 发布网站出现<compilation debug="true" targetFramework="4.6.1">错误

    参考:http://www.mamicode.com/info-detail-1180214.html 原因是环境只安装到.net Framework 4.5 的版本(.net版本向下兼容 ) 解决方 ...

  5. SQL 常用语句(一)

    --SQL 语句为表添加字段并设置默认值 alter table TableName add ColumnName int --字段类型 not null --是否为空 --默认值 --SQL 语句为 ...

  6. Cannot change column 'id': used in a foreign key constraint

    原因:为表添加自增长,但由于该表有外键而报错 发现是因为外键的影响,不能随便的更改表结构. 要想更改表结构,首先要把基层的表修改了. A表 作为B表的外键,A表不能随便修改. B表 有A表的外键,必须 ...

  7. 跨域问题解决----NO 'Access-Control-Allow-Origin' header is present on the requested resource.Origin'http://localhost:11000' is therfore not allowed access'

    NO 'Access-Control-Allow-Origin' header is present on the requested resource.Origin'http://localhost ...

  8. vue项目上传到OSS

    1.输入阿里云登陆地址 http://signin.aliyun.com/1987179281335458/login.htm 登陆地址 阿里云账号    2.选择对象oss,建议文件夹   3.将文 ...

  9. 6-基于TMS320C6678、FPGA XC5VSX95T的6U CPCI 8路光纤信号处理卡

    基于TMS320C6678.FPGA XC5VSX95T的6U CPCI 8路光纤信号处理卡 1.板卡概述  本板卡由我公司自主研发,基于CPCI架构,符合CPCI2.0标准,采用两片TI DSP T ...

  10. Taro -- 微信小程序登录

    Taro微信小程序登录 1.调用Taro.login()获取登录凭证code: 2.调用Taro.request()将code传到服务器: 3.服务器端调用微信登录校验接口(appid+appsecr ...