顺序双向循环队列队列中的每个成员分别有什么作用

以下试题来自:
多项选择题队列研究中,队列的成员哪些特征是不必须的()。
A.同年出生
B.有相同的性别
C.居住在同一地区
D.有相同的暴露史
E.经历过相同的时期
为您推荐的考试题库
您可能感兴趣的试卷
你可能感兴趣的试题
A.前者信息真实性强,后者较差
B.前者可以计算发病率,后者则不可以
C.前者是前瞻性的,后者是回顾性的
D.前者是由因及果,后者由果及因
E.对照组的特征是前者除暴露因素均为同质,后者很难同质
C.多重对照
D.病例对照
E.总人口对照
A.设立对照
B.属于观察性研究方法
C.观察方向是前瞻性的
D.能够验证暴露与疾病之间的因果关系
E.能准确的估计人群发病的危险程度
A.各种病人
B.病原携带者
C.已感染的动物
D.媒介物,如衣物、食品、医疗器械
E.一般人群
A.无明显指征用药
B.用药配伍不当
C.广谱抗生素局部应用
D.大量使用青霉素
E.使用抗病毒药物程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
Cocos2D研究院之触摸信息的接收与传递(七)
Cocos2D研究院之触摸信息的接收与传递(七)
围观6155次
编辑日期: 字体:
通过对场景、层以及精灵的学习,现在我们已经可以制作出一个视觉效果不错的游戏了,但这还远远不够,因为游戏与电影的最大区别就是有互动性,所以我们还必须给它加上操控功能。这次我就着重介绍一下cocos2d中对触摸操作的响应。
前面提到过,层(CCLayer)是cocos2d中传递触摸信息的载体,系统会将接收到的触摸事件传递给层的对象,默认情况下激活场景包含的所有层对象都会收到该信息,但也有一个特殊的层是例外,那就是——菜单(CCMenu)。
CCMenu其实也继承自CCLayer,因此他们都可以加收到触摸信息,但不同的是,CCMenu会“吞掉”自己接受到的触摸事件,使该信息无法传递给它后面的层,这也很好理解,假如有若干个层叠在一起的按钮,那么当我们点击的时候,响应的肯定是最上边那个,如果所有按钮都响应,那用户就要头大了……菜单就是根据这一特性而从层中被单独抽象出来的,它使得UI中同时只会有一个控件被选中。
那么层又是如何接收到玩家的触摸事件的呢?它和IOS系统又是怎样交互的?答案都在CCTouchDispatcher这个类中。
CCTouchDispatcher是个单例,程序刚启动时,导演类会将其设为EAGLView触摸代理,当玩家有触摸操作时,系统会自动调用它的对应方法。之前在介绍层的时候提到过,CCLayer通过registerWithTouchDispatcher方法将自己注册到CCTouchDispatcher单例中,CCTouchDispatcher检测到触摸信息后,会在注册队列中遍历这些对象,调用它们的响应方法,使它们可以响应触摸事件。下面来介绍一下CCTouchDispatcher的变量和方法。
NSMutableArray* standardHandlers
标准注册队列,其实就是一个数组,当CCLayer对象调用registerWithTouchDispatcher方法时,会将其添加到该数组中,所有该数组中的对象在玩家触摸屏幕时都会被调用自身的相关方法,这些方法有(ccTouchesBegan:withEvent:)、(ccTouchesMoved:withEvent:)、(ccTouchesEnded:withEvent:)和(ccTouchesCancelled:withEvent:)。
NSMutableArray* targetedHandlers
目标注册队列,和standardHandlers一样也是个数组,它的作用和standardHandlers大体相同,唯一的区别就是targetedHandlers可以“吞掉”自身响应的事件,以阻止信息继续向下传递,而standardHandlers没有此功能。CCMenu就是向该队列注册的。
BOOL locked
是否被锁定,当玩家做了触摸操作,CCTouchDispatcher开始遍历注册队列时,该变量会被置为YES,此时是不能向队列中添加新的对象,或者从队列中删除对象的,只有当遍历结束,locked被置回NO后,才可以添加或删除,如果在锁定过程中执行了这两种操作,那么操作对象会被放入对应的临时队列中,解琐后再把他们同步到注册队列中。
BOOL toAdd
是否有等待添加的对象,当CCTouchDispatcher被锁定时,如果有新的对象要注册进来,则会被添加进一个临时队列,该队列的所有成员都是待注册对象,如果队列不为空,toAdd就会被值为YES,那么当锁定解除后,就会把该队列的所有成员全部移入standardHandlers或targetedHandlers(它会根据对象的类型自行区分),操作完成后清空临时队列,toAdd置回NO。
BOOL toRemove
是否有等待删除的对象,同添加一样,在CCTouchDispatcher被锁定时,需要删除的对象会被放入另一个临时队列,该队列的成员都是等待注销的,如果队列不为空,toRemove就会被值为YES,锁定解除后再将队列成员依此从注册队列中删除(具体哪个队列会自动判断),操作完成后清空临时队列,toRemove置回NO。
NSMutableArray* handlersToAdd
存放等待注册对象的队列,如前面介绍的,这个数组就是存放待注册对象的临时队列。
NSMutableArray* handlersToRemove
存放等待注销对象的队列,如前面介绍的,这个数组就是存放待注销对象的临时队列。
BOOL toQuit
是否要清空注册队列,同toRemove一样,清空队列同样要等到解锁后才能执行,这个变量就是标记是否需要清空的。
BOOL dispatchEvents
有触摸操作时,是否遍历注册队列,默认一直是YES,需要时可以手动将其置为NO。
struct ccTouchHandlerHelperData handlerHelperData[kCCTouchMax]
一个长度为kCCTouchMax的结构体队列,kCCTouchMax = 4,每个成员都是一个ccTouchHandlerHelperData结构体,用来存储kCCTouchBegan、kCCTouchMoved、kCCTouchEnded和kCCTouchCancelled四种触摸事件的调用方法。结构体有三个数据,前两个是SEL,standardHandlers中的对象会调用touchesSel,targetedHandlers中的对象会调用touchSel,最后的ccTouchSelectorFlag是枚举,用来标记触摸事件的类型。
*四种类型对应的touchesSel分别为:(ccTouchesBegan:withEvent:)、(ccTouchesMoved:withEvent:)、(ccTouchesEnded:withEvent:)、(ccTouchesCancelled:withEvent:)。
*四种类型对应的touchSel分别为:(ccTouchBegan:withEvent:)、(ccTouchMoved:withEvent:)、(ccTouchEnded:withEvent:)、(ccTouchCancelled:withEvent:)。
*也就是说注册队列中的对象至少要实现上述两组方法中的一组,否则有可能会抛异常。
以下是CCTouchDispatcher的方法
+ (CCTouchDispatcher*)sharedDispatcher
获取单例对象,单例类的惯用方法。
-(id) init
初始化方法,将dispatchEvents置为YES,toRemove、toAdd、toQuit、locked均置为NO,给targetedHandlers、standardHandlers、handlersToAdd、handlersToRemove开辟内存空间,并给handlerHelperData中的成员赋值。
-(void) forceAddHandler:(CCTouchHandler*)handler array:(NSMutableArray*)array
向队列array中添加CCTouchHandler对象,CCTouchHandler类的作用就是封装要注册触摸功能的对象,它有两个重要属性,delegate和priority,delegate就是要注册的对象,而priority是它的优先级,优先级越高的对象越先接收到触摸信息。此方法中会根据handler.priority的大小把它插入到队列的适合的位置上。
-(void) addStandardDelegate:(id&CCStandardTouchDelegate&) delegate priority:(int)priority
向standardHandlers队列中添加对象,参数priority为优先级,在一开始会先根据delegate和priority创建一个CCStandardTouchHandler对象(CCStandardTouchHandler是CCTouchHandler的子类,delegate是它的代理),然后再判断当前是否被锁定,如未锁定,则调用前面说的forceAddHandler方法直接添加进standardHandlers数组,如已被锁定,则添加到handlersToAdd数组中等待同步。
*CCLayer中的registerWithTouchDispatcher方法其实就是调用了该函数,priority为0。
-(void) addTargetedDelegate:(id&CCTargetedTouchDelegate&) delegate priority:(int)priority swallowsTouches:(BOOL)swallowsTouches
向targetedHandlers队列中添加对象,参数swallowsTouches表示是否有“吞”事件的功能,YES为有,其他同上。
*CCMenu中的registerWithTouchDispatcher方法其实就是调用了该函数,priority为-128,swallowsTouches为YES。
-(void) forceRemoveDelegate:(id)delegate
从注册队列中删除一个对象,即取消它的触摸功能。该方法会依此遍历standardHandlers和targetedHandlers两个数组,如果某个成员的delegate参数和要注销的对象是同一个,那么就将该成员从队列中删除。
-(void) removeDelegate:(id) delegate
注销一个对象,如果未锁定,则调用上面的forceRemoveDelegate直接将其删除,如果被锁定,则添加进toRemove等待同步。
-(void) forceRemoveAllDelegates
清空standardHandlers和targetedHandlers数组,即取消所有对象的触摸功能。
-(void) removeAllDelegates
注销全部对象,如果未锁定,则调用上面的forceRemoveAllDelegates直接清空队列,如果被锁定,则将toQuit置为NO,等解锁后再清空。
-(CCTouchHandler*) findHandler:(id)delegate
根据代理对象delegate在队列中查找封装它的CCTouchHandler对象,并返回。
NSComparisonResult sortByPriority(id first, id second, void *context)
数组成员的排序方式,该方法用来重新整理注册队列的顺序,将priority值小的放在后面,大的放在前面,因为队列是从前向后遍历的,所以这样可以保证优先级高的对象先收到信息。
-(void) rearrangeHandlers:(NSMutableArray*)array
根据sortByPriority规则给数组array重新排序(由规则可知该数组存的必须是CCTouchHandler对象)。
-(void) setPriority:(int) priority forDelegate:(id) delegate
改变对象的优先级,之后会调用rearrangeHandlers方法给standardHandlers和targetedHandlers重新排序。
-(void) touches:(NSSet*)touches withEvent:(UIEvent*)event withTouchType:(unsigned int)idx
CCTouchDispatcher最重要、最核心的方法,作用就是将玩家的触摸信息传递给在它这里注册过的对象(比如CCLayer、CCMenu)。touches和event是系统提供的,不多说了,idx就是触摸的类型,包括:kCCTouchBegan、kCCTouchMoved、kCCTouchEnded和kCCTouchCancelled。工作流程如下:
首先,将locked置为YES,锁定队列;接着就是遍历targetedHandlers(CCMenu注册的队列,即可以“吞掉”事件),如果idx为kCCTouchBegan,那么会调用(ccTouchBegan:withEvent:)方法,并判断是否是有效触碰,如果是,将该信息添加到对象的claimedTouches中。如果事件的claimedTouches集合已经包含了该触摸信息,则表示现在是kCCTouchMoved、kCCTouchEnded或者kCCTouchCancelled状态,那么就调用这些状态对应的方法,最后判断是否要吞掉事件,如果是则停止遍历;然后遍历standardHandlers,流程和targetedHandlers大致相同,只是没有吞事件的步骤了;两个队列都遍历完成后,locked被置回NO,接下来的工作就是同步添加和删除的操作了。
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
玩家刚刚触碰屏幕时系统调用的方法(导演已将其设为触摸代理),如果dispatchEvents为YES,则调用(touches:withEvent:withTouchType:)方法,类型为kCCTouchBegan。
– (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
手指在屏幕上滑动时系统调用的方法,如果dispatchEvents为YES,则调用(touches:withEvent:withTouchType:)方法,类型为kCCTouchMoved。
– (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
手指离开屏幕时系统调用的方法,如果dispatchEvents为YES,则调用(touches:withEvent:withTouchType:)方法,类型为kCCTouchEnded。
– (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
系统中断时调用的方法,如果dispatchEvents为YES,则调用(touches:withEvent:withTouchType:)方法,类型为kCCTouchCancelled。
以上就是CCTouchDispatcher的工作原理,如果读者一时没有看懂也没关系,因为它在cocos2d中的作用就是底层支持,很少需要对其进行直接操作,我们只要知道如何使用CCLayer和CCMenu,以及注册触摸功能就已经足够开发游戏了。所以接下来我再介绍下CCMenu类。
CCMenu是CCLayer的子类,因此它就是一个特殊的层,它的特殊之处就在于它是针对游戏的UI而设计的。CCMenu的子节点必须是CCMenuItem(cocos2d中的UI控件)或它的子类,因此CCMenu也可以看成是一个UI控件的容器,这些控件只有放到CCmenu的子节点中才能正常工作。下面介绍一下它的属性和方法:
tCCMenuState state_
枚举,用来标记CCMenu对象当前的状态,kCCMenuStateTrackingTouch表示有控件被选中,kCCMenuStateWaiting表示没有控件被选中。
CCMenuItem
*selectedItem_
当前选中的控件,CCMenu可以容纳N个控件,但由CCTouchDispatcher的工作原理我们可以了解到,玩家一次只能选中一个,该变量就是用来保存选中的那个控件的内存地址的。
透明度,该参数和精灵中的opacity_的作用是相同的,不清楚的朋友请参照第六章,这里就不赘述了。
ccColor3B color_
色值,和精灵的参数是一样的,可以参照第六章。
+(id) menuWithItems: (CCMenuItem*) item, …
根据一个CCMenuItem序列创建一个CCMenu对象,序列中的所有成员均为该对象的子节点。
-(id) initWithItems: (CCMenuItem*) item vaList: (va_list) args
根据CCMenuItem序列初始化CCMenu对象。
-(void) addChild:(CCMenuItem*)child z:(NSInteger)z tag:(NSInteger) aTag
添加一个子节点,内容大致和CCNode相同,只是子节点必须为CCMenuItem或它的子类。
– (void) onExit
取消触摸功能,即从CCTouchDispatcher处注销。如有控件被选中,则取消其选中状态,并将state_置为kCCMenuStateWaiting。
-(void) registerWithTouchDispatcher
和CCLayer中的作用一样,只是CCMenu调用的是addTargetedDelegate方法,可以吞掉触摸事件,优先级为-128。
-(CCMenuItem *) itemForTouch: (UITouch *) touch
判断触摸事件是否为有效触摸,原理就是遍历所有子节点,检测触摸点是否在其区域范围内,如有符合条件的子节点则将其返回。
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
玩家开始触碰屏幕时会被CCTouchDispatcher调用,会调用itemForTouch方法检测该操作是否有点中控件,如有,则将其置为选中状态,同时用selectedItem_进行标记并将状态置为kCCMenuStateTrackingTouch。如果CCMenu对象的状态不为kCCMenuStateWaiting或者已被隐藏,那么所有逻辑将不会执行,即已经被选中或者隐藏的控件不会有触摸判定。
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
手指离开屏幕时会被调用,取消已选中控件的选中状态,将自身的state_置为kCCMenuStateWaiting。
-(void) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event
系统中断时调用的函数。
-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
手指滑动时调用的函数。
-(void) alignItemsVertically
将所有包含的控件垂直排列。
-(void) alignItemsHorizontally
水平排列控件。
– (void) setOpacity:(GLubyte)newOpacity
设置透明度。
-(void) setColor:(ccColor3B)color
设置色值。
本章介绍的两个类再加上CCLayer,基本就是cocos2d处理游戏触摸机制的全部手段,下一章我会介绍下控件类——CCMenuItem及其子类,并写一个相关的例子,希望能帮到大家:)如果对博客内容有疑问,欢迎一起交流~
本文固定链接:
转载请注明:
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:失落的宇宙
人的生命是有限的,但bug是无限的,我要把有限的生命投入到无限的改bug事业中去~
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!队列(常用数据结构之一)_百度百科
声明:百科词条人人可编辑,词条创建和修改均免费,绝不存在官方及代理商付费代编,请勿上当受骗。
?常用数据结构之一
(常用数据结构之一)
队列是一种特殊的,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
队列是一种特殊的,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)。[1]
队列顺序队列
建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间,并设置两个指针进行管理。一个是队头指针front,它指向队头元素;另一个是队尾指针rear,它指向下一个入队元素的存储位置,如图所示
每次在队尾插入一个元素是,rear增1;每次在队头删除一个元素时,front增1。随着插入和删除操作的进行,队列元素的个数不断变化,队列所占的存储空间也在为队列结构所分配的连续空间中移动。当front=rear时,队列中没有任何元素,称为空队列。当rear增加到指向分配的连续空间之外时,队列无法再插入新元素,但这时往往还有大量可用空间未被占用,这些空间是已经出队的队列元素曾经占用过得存储单元。
顺序队列中的溢出现象:
(1) &下溢&现象:当队列为空时,做出队运算产生的溢出现象。“下溢”是正常现象,常用作程序控制转移的条件。
(2)&真上溢&现象:当队列满时,做进栈运算产生空间溢出的现象。“真上溢”是一种出错状态,应设法避免。
(3)&假上溢&现象:由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。该现象称为&假上溢&现象。
队列循环队列
在实际使用队列时,为了使队列空间能重复使用,往往对队列的使用方法稍加改进:无论插入或删除,一旦rear指针增1或front指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。自己真从MaxSize-1增1变到0,可用取余运算rear%MaxSize和front%MaxSize来实现。这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列。除了一些简单应用之外,真正实用的队列是循环队列。[2]
在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件时front=rear,而队列判满的条件时front=(rear+1)%MaxSize。队空和队满的情况如图:
队列队列的数组实现
队列可以用数组Q[1…m]来存储,数组的上界m即是队列所容许的最大容量。在队列的运算中需设两个:head,队头指针,指向实际队头元素;tail,队尾指针,指向实际队尾元素的下一个位置。一般情况下,两个的初值设为0,这时队列为空,没有元素。数组定义Q[1…10]。Q(i) i=3,4,5,6,7,8。头head=2,尾指针tail=8。队列中拥有的元素个数为:L=tail-head。现要让排头的元素出队,则需将头指针加1。即head=head+1这时头指针向上移动一个位置,指向Q(3),表示Q(3)已出队。如果想让一个新元素入队,则需尾向上移动一个位置。即tail=tail+1这时Q(9)入队。当队尾已经处理在最上面时,即tail=10,如果还要执行入队操作,则要发生&上溢&,但实际上队列中还有三个空位置,所以这种溢出称为&&。
克服的方法有两种。一种是将队列中的所有元素均向低地址区移动,显然这种方法是很浪费时间的;另一种方法是将存储区看成是一个首尾相接的环形区域。当存放到n地址后,下一个地址就&翻转&为1。在结构上采用这种技巧来存储的队列称为。
队列和栈一样只允许在断点处插入和删除元素。
循环队的入队算法如下:
1、tail=tail+1;
2、若tail=n+1,则tail=1;
3、若head=tail,即尾与头指针重合了,表示元素已装满队列,则作上溢出错处理;
4、否则,Q(tail)=X,结束(X为新入出元素)。
队列和栈一样,有着非常广泛的应用。
注意:(1)有时候队列中还会设置表头结点,就是在队头的前面还有一个结点,这个结点的数据域为空,但是域指向队头元素。
(2)另外,上面的计算还可以利用下面给出的公式cq.rear=(cq.front+1)/
当有表头结点时,公式变为cq.rear=(cq.front+1)/(max+1)。
队列队列的链表实现
在队列的形成过程中,可以利用线性链表的原理,来生成一个队列。
基于的队列,要动态创建和删除节点,效率较低,但是可以动态增长。
队列采用的FIFO(first in first out),新元素(等待进入队列的元素)总是被插入到的尾部,而读取的时候总是从链表的头部开始读取。每次读取一个元素,释放一个元素。所谓的动态创建,动态释放。因而也不存在溢出等问题。由于由间接而成,遍历也方便。
队列队列的基本运算
(1)初始化队列:Init_Queue(q) ,初始条件:队q 不存在。操作结果:构造了一个空队;
(2)入队操作: In_Queue(q,x),初始条件: 队q 存在。操作结果: 对已存在的队列q,插入一个元素x 到队尾,队发生变化;
(3)出队操作: Out_Queue(q,x),初始条件: 队q 存在且非空,操作结果: 删除队首元素,并返回其值,队发生变化;
(4)读队头元素:Front_Queue(q,x),初始条件: 队q 存在且非空,操作结果: 读队头元素,并返回其值,队不变;
(5)判队空操作:Empty_Queue(q),初始条件: 队q 存在,操作结果: 若q 为空队则返回为1,否则返回为0。[3]
求字符串s的长度
s:='';
l:=length(s);{l的值为9}
copy(s,w,k)
复制s中从w开始的k位
s:='';
s1:=copy(s,3,5);{s1的值是'34567'}
val(s,k,code)
将字符串s转为数值,存在k中;code是错误代码
  var s:k,code:
s:='1234';
val(s,k,code);
write(k);{k=1234}
将数值i转为字符串s
  i:=1234;
write(s);{s='1234'}
Delete(s,w,k)
在s中删除从第w位开始的k个字符
  s := 'Honest Abe Lincoln';
Delete(s,8,4);
Writeln(s); { 'Honest Lincoln' }
Insert(s1, S, w)
将s1插到s中第w位
  S := 'Honest Lincoln';
Insert('Abe ', S, 8); { 'Honest Abe Lincoln' }
求字符c在s中的位置
S := ' 123.5';
i :=Pos(' ', S);{i的值为1}
将两个字符串连接起来
  s1:='1234';
s2:='5678';
s:=s1+s2;{';}
在STL中,对队列的使用很是较完美
下面给出循环队列的运算算法:
(1)将循环队列置为空
//将队列初始化
SeQueue::SeQueue()
{ front=0;
cout&&&init!&&&
(2)判断循环队列是否为空
int SeQueue::Empty()
{ if(rear==front) return(1);
else return(0);
(3)在循环队列中插入新的元素x
void SeQueue::AddQ(ElemType x)
{ if((rear+1) % MAXSIZE==front) cout&&& QUEUE IS FULL! &&&
else{ rear=(rear+1) % MAXSIZE;
elem[rear]=x;
cout&&& OK!&;
(4)删除队列中队首元素
ElemType SeQueue::DelQ()
{ if(front==rear)
{ cout&&& QUEUE IS EMPTY! &&& return -1;}
else{ front=(front+1) % MAXSIZE;
return(elem[front]);
(5)取队列中的队首元素
ElemType SeQueue::Front()
if(front== rear)
cout&&&QUEUE IS EMPTY &&&
else x= elem[(front+1)%MAXSIZE];
return (x);
.网路科技时代.2004年02[引用日期]
.电脑与知识技术.2005年15[引用日期]
.信息技术[引用日期]
中国电子学会(Chinese Instit...
提供资源类型:内容可以假想军训的时候理解
服务器君一共花费了226.380 ms进行了6次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议
如何判断一个是否满的?
假设我们在军训中排队,每个人报数。一个队列只能站10个人,从1报到10,队就满了。后来呢,队头的两个人出队了,然后又补充了两个新队员,那么这时候的报数是3到12。这时队列也是满的。
是不是有点思路了?没错,满足(12 + 1) mod 10 = 0就能说明队满了。所以条件就是 (Q->rear+1)%MAXSIZE == Q->front ,队头指针加1再mod队列长度,如果值为0,就说明队满。程序如下:
/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
if ((Q->rear+1)%MAXSIZE == Q->front) /* 队列满的判断 */
return ERROR;
// to do ……
我们在定义队列的结构体的时候并没有一个单独的变量来记录队列的长度,比如前面谈到栈的时候,我们在定义结构体的时候,多定义了一个 来记录长度,这时移动指针也是很方便。
虽然我们在定义队列的时候没这个长度变量,但是我们可以通过模计算来取得我们需要的。将队尾指针向后移动一位?很简单,Q->rear = (Q->rear+1)%MAXSIZE; 即可。
所以函数设计成这样:
/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
if ((Q->rear+1)%MAXSIZE == Q->front) /* 队列满的判断 */
return ERROR;
Q->data[Q->rear]=e;
/* 将元素e赋值给队尾 */
Q->rear=(Q->rear+1)%MAXSIZE;/* rear指针向后移一位置, */
/* 若到最后则转到数组头部 */
#include "stdio.h"
#include "stdlib.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int S
/* QElemType类型根据实际情况而定,这里假设为int */
typedef int QElemT
/* 循环队列的顺序存储结构 */
typedef struct
QElemType data[MAXSIZE];
/* 头指针 */
/* 尾指针,若队列不空,指向队列尾元素的下一个位置 */
/* 初始化一个空队列Q */
Status InitQueue(SqQueue *Q)
Q->front=0;
Q->rear=0;
Status visit(QElemType c)
printf("%d ",c);
return OK;
/* 从队头到队尾依次对队列Q中每个元素输出 */
Status QueueTraverse(SqQueue Q)
while((i+Q.front)!=Q.rear)
visit(Q.data[i]);
i=(i+1)%MAXSIZE;
printf("\n");
return OK;
/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
if ((Q->rear+1)%MAXSIZE == Q->front) /* 队列满的判断 */
return ERROR;
Q->data[Q->rear]=e;
/* 将元素e赋值给队尾 */
Q->rear=(Q->rear+1)%MAXSIZE;/* rear指针向后移一位置, */
/* 若到最后则转到数组头部 */
int main()
SqQueue Q;
InitQueue(&Q);
printf("\n1.给队列附初始值 \n2.遍历队列 \n3.入队 ");
printf("\n0.退出 \n请选择你的操作:\n");
while(opp != '0')
scanf("%d",&opp);
switch(opp)
srand(time(0));
for(j=1; j<=10; j++)
d = rand()%100+1;
EnQueue(&Q,d);
QueueTraverse(Q);
QueueTraverse(Q);
printf("请输入需要入队的元素:");
scanf("%d", &d);
EnQueue(&Q,d);
QueueTraverse(Q);
延伸阅读此文章所在专题列表如下:
本文地址:,欢迎访问原出处。
不打个分吗?
转载随意,但请带上本文地址:
如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 。
大家都在看
现代魔法研究协会欢迎你
阅读一百本计算机著作吧,少年
鲁特兹(Mark Lutz) (作者), 李军 (译者), 刘红伟 (译者), 等 (译者)
《Python学习手册(第4版)》学习Python的主要内建对象类型:数字、列表和字典。使用Python语句创建和处理对象,并且学习Python的通用语法模型。使用函数构造和重用代码,函数是Python的基本过程工具。学习Python模块:封装语句、函数以及其他工具,以便构建较大的组件。学习Python的面向对象编程工具,用于组织程序代码。学习异常处理模型,以及用于编写较大程序的开发工具。了解高级Python工具,如装饰器、描述器、元类和Unicode处理等。
扫一扫,在手机上阅读
栏目最新博文
12,249 views
14,603 views
7,239 views
6,968 views
13,083 views
16,267 views
10,705 views
8,942 views
8,278 views
20,258 views
栏目博文推荐
20,577 views
7,503 views
10,288 views
6,878 views
7,264 views
12,824 views
22,223 views
6,446 views
10,205 views
10,705 views
这辈子没法做太多的事情, 所以每一件都要做到精彩绝伦! ——史蒂夫.乔布斯
关于网站与作者
互联网信息太多太杂,各互联网公司不断推送娱乐花边新闻,SNS,微博不断转移我们的注意力。但是,我们的时间和精力却是有限的。这里是互联网浩瀚的海洋中的一座宁静与美丽的小岛,供开发者歇息与静心潜心修炼(愿景)。
“Veda”的本义是知识、启示,希望这里能为开发者提供充足的技术资料。
我的电子邮件gonnsai(at)163.com,腾讯微博:,欢迎与我联系。

我要回帖

更多关于 队列口令下达顺序 的文章

 

随机推荐