循环队列的顺序存储和入队出队操作

今天看图的广度优先遍历的时候,发现用到了循环队列,补一下循环队列的知识,参考《大话数据结构》的P116~117,自己写了一个简单的测试例子便于理解。

首先需要理解以下三条公式。

front是队头元素的下标,rear是队尾元素后一位的下标。(书上用头指针和尾指针,front和rear并不是指针,个人觉得不太好)

1、队列空的条件

显然front==rear

注意:如果队列不保留任何元素空间

满足front==rear的情况下,可能是队列空,也可能是队列满。所以为了方便,本文讨论的是采用保留一个元素空间的方法。(也可以采用设置标志变量的方法)

2、队列满的条件

队列满只有这两种情况,所以队列满的条件是:

(rear+1)%QueueSize==front

3、队列长度计算公式

同时考虑这两种情况,队列计算公式是:

rear-front+MAXSIZE)%MAXSIZE

MAXSIZE是队列长度(包括那个保留的元素空间)

下面举个简单的例子,实现循环队列的创建,入队和出队操作。

代码和解释如下(Qt Creator测试通过):

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4
 5 #define MAXSIZE 5
 6
 7 //循环队列的顺序存储结构
 8 typedef struct
 9 {
10     char data[MAXSIZE];//队列,用数组形式表示,这里假设最多只有4个元素
11     //保留一个元素空间,否则front==rear,是空队列还是满队列不容易判断
12     int front;//头序号,第一个元素的下标
13     int rear;//尾序号,最后一个元素的下标
14 }SqQueue;
15
16 //循环队列的初始化,返回指向循环队列的地址
17 SqQueue *InitQueue(SqQueue *Q)
18 {
19     Q=new SqQueue;
20     Q->front=0;
21     Q->rear=0;//初始化为空队列(front==rear为空队列)
22     return Q;
23 }
24
25 //求循环队列的长度,返回循环队列的当前长度
26 int QueueLength(SqQueue *Q)
27 {
28     return (Q->rear-Q->front+MAXSIZE)%MAXSIZE;
29 }
30
31 //循环队列的入队列操作
32 void EnQueue(SqQueue *Q,char e)
33 {
34     if((Q->rear+1)%MAXSIZE==Q->front)//判断循环队列是否满
35     {
36         cout<<"error"<<" ";
37         return;
38     }
39     Q->data[Q->rear]=e;//将元素e插入队尾
40     Q->rear=(Q->rear+1)%MAXSIZE;//尾序号rear加1,若到最后转向头部
41     cout<<"ok"<<" ";
42     return;
43 }
44
45 //循环队列的出队列操作
46 char DeQueue(SqQueue *Q)
47 {
48     char e;
49     if(Q->front==Q->rear)//如果队列是否空
50     {
51         cout<<"error"<<" ";
52         return 0;//返回0表示队列空,没有出队元素
53     }
54     e=Q->data[Q->front];
55     Q->front=(Q->front+1)%MAXSIZE;//头序号front加1,若到最后转向头部
56     cout<<"ok"<<" "<<e<<endl;
57     return e;
58 }
59
60 int main(void)
61 {
62     SqQueue *s=NULL;
63
64     //初始化一个空队列s
65     s=InitQueue(s);
66
67     //插入元素,并返回当前队列长度
68     EnQueue(s,‘A‘);//插入A
69     cout<<s->data[0]<<" ";//提示队尾是否插入A(因为初始化时rear=0,所以从下标为0的地方开始插入)
70     cout<<QueueLength(s)<<endl;//输出当前长度1
71
72     EnQueue(s,‘B‘);//插入B
73     cout<<s->data[1]<<" ";//提示队尾是否插入B
74     cout<<QueueLength(s)<<endl;//输出当前长度2
75
76     EnQueue(s,‘C‘);//插入C
77     cout<<s->data[2]<<" ";//提示队尾是否插入C成功
78     cout<<QueueLength(s)<<endl;//输出当前长度3
79
80     EnQueue(s,‘D‘);//插入D
81     cout<<s->data[3]<<" ";//提示队尾是否插入D成功
82     cout<<QueueLength(s)<<endl;//输出当前长度4
83
84     EnQueue(s,‘E‘);//插入E,输出error,说明插入失败
85     cout<<QueueLength(s)<<endl;//输出当前长度4,说明已经满了不能再插入
86
87     //出队
88     DeQueue(s);//输出A
89     DeQueue(s);//输出B
90
91     //再插入元素,理解队列的循环
92     EnQueue(s,‘E‘);//插入E
93     cout<<s->data[4]<<" "<<s->rear<<endl;//提示队尾是否插入E成功,这时候rear挪到下标0的地方了
94     EnQueue(s,‘F‘);//插入F
95     cout<<s->data[0]<<" "<<s->rear<<endl;//提示队尾是否插入F成功,这时候rear挪到下标1的地方了
96     EnQueue(s,‘G‘);//插入G,输出error,说明插入失败
97     cout<<QueueLength(s)<<endl;//输出当前长度4,说明已经满了不能再插入
98 }

运行结果:

时间: 2024-09-28 18:00:19

循环队列的顺序存储和入队出队操作的相关文章

编程实现队列的入队/出队操作

思路:队列其实也是一个链表,只是队列还有两个特殊的结点,一个指向队头,一个指向队尾.先设计数据结构,如下 typedef struct student * PNode; typedef struct linkqueue * Pqueue; typedef struct student { int data; PNode next; }Node; typedef struct linkqueue { PNode first; PNode rear; }queue; 1.入队操作其实是指向队尾的指针

入队/出队

入队/出队操作 #include<iostream> using namespace std; struct node { int data; node *next; }; struct queue { node *head; node *rear; }; //入队 queue *push_queue(queue *team,int x) { node *s=new node; s->data=x; s->next=NULL; if(team->rear==NULL) { t

循环队列的初始化、入队、出队等基本操作

循环队列的初始化.入队.出队等基本操作,实现代码如下: #include<iostream> using namespace std; #define TRUE 1 #define FALSE 0 //循环队列的类型定义 #define MAXSIZE 50//队列的最大长度 typedef struct { int element[MAXSIZE];//队列的元素空间 int front;//头指针指示器 int rear;//尾指针指示器 }SeqQueue; //循环队列初始化 void

JQuery源码分析 --- 运动animate 入队出队

我们都知道,所谓的运动就是操作定时器,但是如果我同时写3个运动,比如下面这样,效果会怎样呢? <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #div1{ width: 300px; height: 300px; background: red

队列的入队和出队操作

#include<iostream> #include<stdio.h> #include<string.h> #include<conio.h> using namespace std; typedef struct student{ int data; struct student *next; }node; typedef struct linkqueue { node *first, *rear; }queue; //队列的入队 queue *ins

Java数据结构系列之——队列(2):循环队列的顺序存储结构及其实现

package queue.circleSequenceQueue; /** * 这里我们规定队列满时数组中还有一个空闲空间,不允许将数组中的空间全部存满 * 循环队列满的条件是:(rear+1)%QueueSize==front * 长度计算公式为:(rear-front+QueueSize)%QueueSize * @author wl */ public class CircleSequenceQueue { Object[] elementData;//数组用于存放队列元素 int fr

数据结构学习之循环队列(顺序存储)

[摘要]队列特性:先进先出(FIFO)--先进队列的元素先出队列.来源于我们生活中的队列(先排队的先办完事). 这样有个缺陷,空间利用率不高,所以我们直接学习循环队列(基于连续内存的). (1)设计队列数据结构 typedef struct _QUEUE_NODE { int* pData; int length;//队列长度 int head ;//队头指针 int tail;//队尾指针 int count;//队列元素当前个数 }QUEUE_NODE; (2)申请队列内存 QUEUE_NO

(源代码见大话数据结构)线性表—循环队列的顺序存储结构

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 20 typedef int Status; typedef int QElemType; typedef struct { QElemType data[MAXSIZE]; int front; int rear; }SqQueue; Status In

循环队列(0965)

p { margin-bottom: 0.25cm; line-height: 120% } 描述 根据给定的空间构造顺序循环队列,规定队满处理方法为少用一个元素空间.例如,给定5个元素空间构造循环队列,则只能存放4个元素.试根据入队及出队操作判断队列最后的元素存放情况,并输出最后队列中的元素值,即完成给定入队及出列操作后一次性全部出队的元素值.要求采用顺序队列完成,少用一个存储空间的方法区分队列的空和满. input 输入的第一行为一个自然数n,表示要求构造的顺序循环队列空间数. 第二行为操作