队列问题非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. Kotlin学习(3)类

    声明类和接口: //类 class A{ } //接口,接口中的方法可以有默认实现 interface B{ fun show(){ print("i'm B") } } //用冒 ...

  2. P5444 [APIO2019]奇怪装置

    传送门 考虑求出最小的循环节 $G$ 使得 $t,t+G$ 得到的数对是一样的 由 $y \equiv t \mod B$ ,得到 $G$ 一定是 $B$ 的倍数,设 $zB=G$,则 $t,t+zB ...

  3. [环境搭建]-Web Api搭建到IIS服务器后PUT请求返回HTTP Error 405.0 - Method Not Allowed 解决方法 转摘:http://blog.csdn.net/qiujuer/article/details/23827531

    尝试使用微软的Web Api,他的确是一个很有意思的东西. 让我体会到了许多的方便,但是我发现部署到IIS服务器上去了后PUT和Delete请求将返回405. 原因是IIS的默认处理程序默认情况下只允 ...

  4. addEventListener 的三个参数

    addEventListener 有三个参数:第一个参数表示事件名称(不含 on,如 "click"):第二个参数表示要接收事件处理的函数:第三个参数为 useCapture,本文 ...

  5. onupdate

    数据的初始化显示刚开始写在onupdate中,文档类中的数据更新之后,希望通过调用UpdateAllViews(FALSE)来实现视图的更新,可以实现!后来觉得不妥,想把初始化显示写在ondraw中, ...

  6. MacOS系統Flutter打包apk

    一.打包前需要做一些基本设置的确认 1.应用名 2.权限设置 3.applicationId:应用唯一标识符 4.versionCode:版本号 5.versionName:版本名称 6.APP应用图 ...

  7. 未来HTML5的发展前景如何?黑客专家是这样回答的

    如果你想进军IT行业,如果你准备好掌握一项新技术,那么就选择HTML5.近日,我们采访了国内知名网络黑客安全专家郭盛华,帮助您了解当今最重要的技术.在本篇文章中,黑客安全专家郭盛华回答了有关HTML5 ...

  8. Ubuntu下批量使用Tecplot的preplot命令对数据进行处理

    首先把.PLT文件后缀批量修改为.dat rename 's/.PLT$/.dat/' *.PLT 对所有.dat文件批量执行preplot find ./ -name "*.dat&quo ...

  9. final、finally、 finalize区别

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11444366.html final final可以用来修饰类.方法.变量,分别有不同的意义,final ...

  10. Jenkins必备插件

    1.汉化插件 https://plugins.jenkins.io/localization-zh-cn 2.邮件发送 https://plugins.jenkins.io/email-ext 3.G ...