数据结构:循环队列

数组表示的问题 

    对于队列最好的方法是使用链表实现,因为对于数组来说,队列可能会出现下面这种情况:

    

    如图所示,不可以继续添加元素,否则会造成数组越界而遭致程序出错。然而此时又不应该扩充数组,因为还有大量实际空间未被占用。

    此时我们应该如何解决这个问题呢?我们将其实现为循环队列

理解循环队列

    何谓循环队列?首先我们要说明的是循环队列仍然是基于数组实现的。但是为了形象化的说明问题,我们如下图所示

          

    1.图中有两个指针(其实就是两个整数型变量,因为在这里有指示作用,所以这里理解为指针)front、rear,一个指示队头,一个指示队尾。

    2.rear和front互相追赶着,这个追赶过程就是队列添加和删除的过程,如果rear追到head说明队列满了,如果front追到rear说明队列为空。

  说明:

    令队列空间中的一个单元闲置,使得队列非空时,Q.rear与Q.front之间至少间隔一个空闲单。

    3.我们把它掰弯,用的是求余,这样两个值就不会跑出最大范围,并且可以实现弯曲的效果,所以说对于循环队列我们必须给定最大值MAXQSIZE。

       这其实是我们臆想的,反正我们要做的就是利用循环来解决空间浪费的问题。  

循环队列的实现过程

    ☆当添加一个元素时,(rear+1)%MAXQSIZE; //理解为什么求余?

    ☆当删除一个元素时,(front+1)%MAXQSIZE;//理解为什么求余?

    ☆当rear=front的时候,队列可能是满,也可能是空。

      因为存在满和空两种情况,我们需要分别判断:

        ☆:当队列添加元素到rear的下一个元素是head的时候,也就是转圈子要碰头了,我们就认为队列满了。(Q.rear+1)%MAXSIZE=Q.front

        ☆:当队列删除元素到head=rear的时候,我们认为队列空了。Q.rear==Q.front,不一定为0

  图示:

    

队列操作的一些说明

队列长度:Q.rear-Q.front;

队头元素:Q.base[Q.front];

队尾元素:Q.base[Q.rear-1];

2.代码分解

2.1添加操作

   元素入队时仅修改队尾指针rear —— ++.

1 status EnQueue(SqQueue *q,QElemtype e)
2 {
3     //插入到队尾
4     if((q->rear+1)%MAXQSIZE==q->front)
5         return 0;
6     q->base[q->rear]=e;
7     q->rear=(q->rear+1)%MAXQSIZE;
8     return 1;
9 }

2.2删除操作

    元素出队列时只修改队头指针front——++.

1 status DeQueue(SqQueue *q)
2 {
3     if(q->front==q->rear)
4         return 0;
5     printf("%d",q->base[q->front]);
6     q->front =(q->front+1)%MAXQSIZE;
7     return 1;
8 }

2.3获取队列长度

1 int QueueLength(SqQueue *q)
2 {
3     return (q->rear-q->front+MAXQSIZE)%MAXQSIZE;
4 }

2.4对节点的定义

1 #define MAXQSIZE 100
2 typedef int QElemtype;
3 typedef int status;
4
5 typedef struct{
6     QElemtype *base;
7     int front;
8     int rear;
9 }SqQueue;

2.5测试方法

 1 void main()
 2 {
 3     SqQueue *q;
 4     q=(SqQueue*)malloc(sizeof(SqQueue));
 5     q=InitQueue(q);
 6     EnQueue(q,5);
 7     EnQueue(q,4);
 8     EnQueue(q,3);
 9     EnQueue(q,2);
10     EnQueue(q,1);
11     printf("队列长度为:%d\n",QueueLength(q));
12     DeQueue(q);
13     DeQueue(q);
14     DeQueue(q);
15     DeQueue(q);
16     DeQueue(q);
17 }

 2.6初始化队列

SqQueue* InitQueue()
{
    SqQueue *q;
    q=new SqQueue;
    q->base=new int[MAXQSIZE];
    q->rear=q->front=0;
    return q;
}

原文地址:https://www.cnblogs.com/JeasonIsCoding/p/9858968.html

时间: 2024-08-23 14:56:54

数据结构:循环队列的相关文章

大话数据结构----循环队列和链式队列

队列(Queue) 是只允许在一端进行插入操作,而在另一端进行删除操作的线性表 队列的特点就是:先进先出,和生活中排队的例子是很先进的,排队的目的不就是先到先得吗. 生活中的队列相当于顺序存储的队列,在火车站排队买票,前面的人买完票走了,后面的人一个一个往前移一位,这是很正常的事情,而计算机中队列队列第一个元素出去了,后面的元素一个一个往前移,这是一件很降低效率的一件事.为了解决这种效率问题,计算机采用循环队列的方式操作队数据. 循环队列 队列的头尾相接的顺序存储结构称为循环队列. 1.首先循环

数据结构 --- 循环队列(队列的顺序存储结构)

工程目录结构图: common.h: 1 //#ifndef __common_h__ 2 //#define __common_h__ 3 4 #define OK 1 5 #define ERROR 0 6 #define TRUE 1 7 #define FALSE 0 8 9 #define MAXSIZE 20 10 11 typedef int Status; //函数的返回结果,OK.ERREO.TRUE.FALSE 12 typedef int ElemType; //结点数据域

数据结构-循环队列程序演示

1 /* 2 循环队列需要2个参数来确定: 3 front,rear 4 1)队列初始化 5 front和rear的值都为零 6 2)队列非空 7 front代表的是队列的第一个元素 8 rear代表的是队列的最后一个有效元素 9 3)队列空 10 front和rear的值相等,但不一定是零 11 */ 12 13 14 /* 15 队列 16 定义:一种可以实现先进先出的存储结构 17 分类: 18 静态队列 19 链式队列 20 */ 21 #include <stdio.h> 22 #i

数据结构--循环队列

一.顺序队列的改进 队列元素的出列是在队头,即下标为0的位置,那也就意味着,队列中的所有元素都得向前移动,以保证队列的队头(也就是下标为0的位置)不为空,此时的时间复杂度为0(n). 可有时想想,为什么出队列时一定要全部移动呢,如果不去限制队列的元素必须存储在数组的前n个单元这一条件,出队的性能就会大大增加.也就是说,队头不需要一定在下标为0的位置,比如也可以是a[1]等. 而为了避免当只有一个元素时,队头和队尾重合使处理变得麻烦,引入两个指针,front指针指向队头元素,rear指针指向队尾元

数据结构:循环队列及其基本操作的实现

/** * 循环队列 * 队列设置first指针直接指向队列头部元素,tail尾指针指向队列最后一个元素的后一个,即队列中总是预留一个空位 */ class CircleQueue implements Queue<Integer>{ private Integer[] queueArray = null; private int first; private int tail; private int maxSize; public CircleQueue(int max){ this.ma

数据结构Java实现07----队列:顺序队列&amp;顺序循环队列、链式队列、顺序优先队列

数据结构Java实现07----队列:顺序队列&顺序循环队列.链式队列.顺序优先队列 一.队列的概念: 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其另一端进行删除操作. 队列中允许进行插入操作的一端称为队尾,允许进行删除操作的一端称为队头.队列的插入操作通常称作入队列,队列的删除操作通常称作出队列. 下图是一个依次向队列中插入数据元素a0,a1,...,an-

数据结构6_顺序队列(循环队列)

本文实现了顺序队列,与链队列不同的是,顺序队列需要考虑一个问题, 问题情况如下, 解决办法:循环队列,当rear到分配的数组空间末尾时,转到数组头 但是当q.rear==q.front时,又如何区分一种是空队列,一种是满队列的情况呢 这里有两种方案 本次代码实现了第一种方法,同时设置了一个技术变量length,稍加改动便可实现第二个方法 代码如下: #include<iostream>using namespace std;//该顺序队列为循环队列,解决队尾指针达到最大值,队列中有空闲单元,但

数据结构——队列及循环队列

说明:严蔚敏的<数据结构>(C语言版)学习笔记,记录一下,以备后面查看. #include <stdio.h> #include <stdlib.h> #define OK 1; #define ERROR -1; typedef int QElemType; typedef int Status; //定义队列节点 typedef struct QNode{ QElemType data; struct QNode *next; }QNode, *QueuePtr;

数据结构算法C语言实现(十二)--- 3.4循环队列&amp;队列的顺序表示和实现

一.简述 空队列的处理方法:1.另设一个标志位以区别队列是空还是满:2.少用一个元素空间,约定以队列头指针在队尾指针下一位置上作为队列呈满的状态的标志. 二.头文件 1 //3_4_part1.h 2 /** 3 author:zhaoyu 4 email:[email protected] 5 date:2016-6-9 6 note:realize my textbook <<数据结构(C语言版)>> 7 */ 8 //Page 64 9 #include <cstdio

基本数据结构,循环队列的顺序实现。

队列是一种先进先出的数据结构,这里用顺序结构将其实现. 1.首先用结构体定义一个队列,front指向队首元素的前面一位,real指向队尾元素. 1 //队列的结构定义 2 #define MAX 6 3 typedef struct { 4 int front,real; 5 int data[MAX]; 6 }queue; 2.创建一个循环队列,初始化令front=real=0,因为当队列满时也有front=real,此时无法判断队满:所以我们弃置一个元素位不用,其位置随机,所以队列的实际最大