salesforce零基础学习(七十七)队列的实现以及应用
队列和栈简单的区别为栈是后进先出,队列是先进先出。队列也是特殊的线性表,所以队列也分为顺序存储结构和链式存储结构。本篇主要描述顺序存储结构。
我们先假定一个队列里有5个元素,当我们添加新元素时,添加到队列的最后一个位置,所以时间复杂度为O(1),当我们弹出元素时,需要将队列头部的元素弹出,并将后面的元素整体向前面平移,所以时间复杂度为O(n)。如果频繁的弹出,并且后面的元素向前面平移,这样对于性能还是影响挺大的,所以我们可以增加头指针,尾指针,不要求第一个元素必须在index为0的位置,只需要用头指针记录当前的头在哪里就好。

一.环形队列:
使用两个指针操作步骤为:
1.当在队尾添加元素情况下,队尾的指针+1,如下图,队列中添加a1,a2,a3,a4四个元素。此时队首front指针指向0,队尾rear指针指向4;
2.将队首元素进行弹出,此时队首指针front指向1,队尾指向4;
3.将元素a5添加到队尾,此时队尾指针指向到了内存长度的外面,但是下标为0还是有空缺的地方,这种情况称为假溢出。

为了避免假溢出这种情况,我们的做法为当队列满了以后,从头开始继续存储队列,直到队列满,即上图的情况下,a5进入队列以后,队尾rear指针指向下标0.
此时针对队列的空或者满的判断,可以通过队首指针和队尾指针来判断:
1.判断队列为空的条件为:front = rear,即首指针等于尾指针;
2.因为队尾可以从头开始,所以rear可以大于front,也有可能rear小于front。当队列满时,我们修改其条件,保留一个元素空间。也就是说,队列满时,数组中还有一个空闲单元。这样我们可以通过下面的表达式来判断队列已满:(rear+1) % QueueSize = front.上图中当添加完a5以后,队列中只剩下一个空闲单元我们就假定此队列已满。
3.获取当前队列的元素个数:(rear - front + QueueSize)% QueueSize
二.代码实现
代码中封装了实现队列的基本方法,判断队列是否为空,是否是满的队列,添加元素,弹出元素等。其中针对添加元素,需要考虑队列是否已经满的情况,对于弹出元素,需要考虑队列是否为空队列的情况。
public with sharing class Queue {
//数据集
private Object[] datas{get;set;}
//栈最大容量
private Integer maxSize{get;set;}
//队头的位置指针
private Integer front{get;set;}
//队尾的位置指针
private Integer rear{get;set;}
public Queue() {
this(10);
}
public Queue(Integer queueSize) {
datas = new Object[queueSize];
maxSize = queueSize;
front = 0;
rear = 0;
}
//添加元素到队列尾部,如果添加成功返回true,添加失败返回false
public Boolean add(Object obj) {
if(datas == null) {
throw new QueueException('队列未初始化');
}
if(full()) {
throw new QueueException('队列已满');
}
datas[rear] = obj;
rear = Math.mod(rear + 1, maxSize);
//队列
return true;
}
//返回队列头的元素,不弹出头元素
public Object peek() {
if(datas == null) {
throw new QueueException('队列未初始化');
}
return datas[front];
}
//弹出头元素
public Object poll() {
if(datas == null) {
throw new QueueException('队列未初始化');
}
if(empty()) {
throw new QueueException('队列为空!');
}
Object returnObj = datas[front];
datas[front] = null;
front = Math.mod((front + 1),maxSize);
return returnObj;
}
public Boolean empty() {
return front == rear;
}
public Boolean full() {
return front == Math.mod(rear + 1, maxSize);
}
public Integer size() {
return Math.mod(rear - front + maxSize ,maxSize);
}
override public String toString() {
List<Object> objList = new List<Object>();
Integer tempRear;
if(rear < front) {
tempRear = rear + maxSize;
} else {
tempRear = rear;
}
for(Integer i = front;i<=tempRear;i++) {
if(datas[Math.mod(i, maxSize)] != null) {
objList.add(datas[Math.mod(i, maxSize)]);
}
}
return String.join(objList, ',');
}
public class QueueException extends Exception{
}
}
三.测试举例:
1.队列超出内存情况:初始化一个长度为5的队列,因为队列满的时候,会空出一个元素空间,所以说实际可以添加进队列的长度为4,当添加eee的时候会报错,因为队列已满。
Queue q = new Queue(5);
q.add('aaa');
q.add('bbb');
q.add('ccc');
q.add('ddd');
q.add('eee');
System.debug(LoggingLevel.INFO, '*** q: ' + q);

2.正常使用添加弹出效果,每次弹出是弹出队首指针对应的元素
Queue q = new Queue(5);
q.add('aaa');
q.add('bbb');
q.add('ccc');
q.add('ddd');
String result = (String)q.poll();
System.debug(LoggingLevel.INFO, '*** result: ' + result);
System.debug(LoggingLevel.INFO, '*** : ' + 'aaa'.equals(result));
q.add('eee');
System.debug(LoggingLevel.INFO, '*** q: ' + q);

总结:环形队列适用于已经知道需要分配多大内存的情况,如果不知道需要分配多少内存的情况,可以使用队列的链形结构。队列在程序中经常使用,比如场景为排队等的场景,如果有此种先进先出的场景,优先选择队列来实现。此篇只是简单的构造一下队列的模型,很多地方需要完善,有需要或者感兴趣的自行完善一下。篇中有错误的地方欢迎指出,有问题欢迎留言。
salesforce零基础学习(七十七)队列的实现以及应用的更多相关文章
- 【转】【Salesforce】salesforce 零基础学习(十七)Trigger用法
看本篇之前可以相应阅读以下Trigger相关文章: 1.https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex_Trigge ...
- salesforce 零基础学习(十七)Trigger用法
看本篇之前可以相应阅读以下Trigger相关文章: 1.https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex_Trigge ...
- salesforce 零基础学习(五十二)Trigger使用篇(二)
第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...
- salesforce零基础学习(八十七)Apex 中Picklist类型通过Control 字段值获取Dependent List 值
注:本篇解决方案内容实现转自:http://mysalesforceescapade.blogspot.com/2015/03/getting-dependent-picklist-values-fr ...
- salesforce零基础学习(八十二)审批邮件获取最终审批人和审批意见
项目中,审批操作无处不在.配置审批流时,我们有时候会用到queue,related user设置当前步骤的审批人,审批人可以一个或者多个.当审批人有多个时,邮件中获取当前记录的审批人和审批意见就不能随 ...
- salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现
项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等.这种情况下可以使用jquery ui中的au ...
- salesforce 零基础学习(六十八)http callout test class写法
此篇可以参考: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restfu ...
- salesforce零基础学习(八十九)使用 input type=file 以及RemoteAction方式上传附件
在classic环境中,salesforce提供了<apex:inputFile>标签用来实现附件的上传以及内容获取.salesforce 零基础学习(二十四)解析csv格式内容中有类似的 ...
- salesforce零基础学习(九十六)Platform Event浅谈
本篇参考:https://developer.salesforce.com/blogs/2018/07/which-streaming-event-do-i-use.html https://trai ...
- salesforce零基础学习(一百零五)Change Data Capture
本篇参考: https://developer.salesforce.com/docs/atlas.en-us.232.0.api_streaming.meta/api_streaming/using ...
随机推荐
- GitBash学习1
昨晚学了一点GitBash,建立库,向库里添加文件,对比修改的内容等等. 自己做了以下总结 git mkdir <dirname> //建立文件 git cd <dirname> ...
- JAVA基础——类和对象
java类与对象学习笔记 一.成员变量和局部变量 (1)定义 1.成员变量 在类中定义,用来描述对象将要有什么.(默认的成员变量值为0) 2.局部变量 在类的方法中定义,在方法中临时保存数据. 演示示 ...
- Openfire开发广播服务接口,支持离线广播消息
Openfire开发广播服务接口,支持离线广播消息 概要 最近公司要求做一个web端向所有移动端发送公告,所以考虑到即时性就用openfire做服务.不过为了减轻web端的工作量,我们开发一个简单的插 ...
- 使用JDK自带的MessageDigest计算消息摘要
使用JDK自带的MessageDigest计算消息摘要 上代码 /** * 使用JDK自带MessageDigest */ public class MessageDigestUtils { /** ...
- web前段学习2017.6.13
CSS---表现层,修饰和表现html文档,为了解决结构层和表现层分离的问题. 通过CSS极大的提高了工作效率,方便工作人员维护和管理CSS:层叠样式表,目前用的最广泛的css版本为css2,最新版本 ...
- 错误代码是1130,ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server 是无法给远程连接的用户权限问题
错误代码是1130,ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server 是无法给远程连接的用 ...
- Matlab: 白噪声与曲线拟合
在信号处理中常常需要用到曲线拟合,这里介绍一下利用最小二乘拟合一般曲线的方法,并对滤掉信号中白噪声的方法作些介绍. 为了测试拟合算法的好坏,先模拟出一个信号作为检验算法的例子: 用白噪声产生模拟信号: ...
- unslider插件的使用
深入理解unslider.js源码 最近用到了一个挺好用的幻灯片插件,叫做unslider.js,就想看看怎么实现幻灯片功能,就看看源码,顺便自己也学习学习.看完之后收获很多,这里和大家分享一下. u ...
- hdu2410(水)
题意 如果两个数字除了带问号的位以外都相同,我们称这两个数可以相互匹配 给你两个数,其中第一个数字里有一些问号,问有多少个大于第二个数的数字可以和第一个数字匹配 一开始懒得读题,到网上搜题意,结果居然 ...
- web.xml is missing and <failOnMissingWebXml> is se
摘要 maven模块化 在学习maven模块化构建项目的时候遇到了如下报错信息: web.xml is missing and <failOnMissingWebXml> is set t ...