什么是队列

我们都知道栈是先进后出的一种线性表,与之相反的是,队列是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端进行删除。举个例子来说,在生活中我们买东西需要进行排队,最先排队的可以最早的离开队伍,而排在最后面的需要最后离开队伍。在队列当中,允许插入的一端称为队尾,而允许删除的一段称为队头。和栈与线性表类似,队列也分为顺序队列和链队列。

普通队列所存在的问题

在使用数组实现的队列中,入队的操作就是将尾指针rear右移一个单位(加一),然后将元素值赋值给rear单位。出队时,则是头指针front后移一个单位(加一)。当进行了一定数量的入队和出队操作后,可能会出现这样的情况:

尾指针rear已指到数组的最后有一个元素,即rear=maxSize-1,此时若再数组的前面部分可能还有很多闲置空间,即这种溢出并非是真的没有可用的存储空间,故称这种溢出现象为“假溢出”。显然,必须要解决这一块假溢出的问题,否则顺序队列就没有太多使用价值。

解决假溢出一般情况下有两个方式:

1.在普通队列中设置元素实际个数变量size,在每次入队或者出队时将size和maxSize进行比较,从而避免假溢出。使用这种方式未免有些繁琐。

2.使用循环队列,将队列掰弯,也就是将队列看成环状结构,即data[0]为紧接着data[MaxLen-1]的单元,为相邻的元素,首位成为一个环,如下所示:

 理解循环队列

首先要确认的是,循环队列仍然是基于数组实现的,使用一组地址连续的存储单元依次存放从队头到队尾的元素,且仍然设置两个指针front,rear。注意的是,其实这两个指针是整数型的,起得是知识的作用便于理解,所以称之为指针。这两个指针,一个指着队头,一个指着队尾。

这两个指针可以看做动态的过程,即这两个指针其实是互相追赶的。在追赶中就是队列中元素添加和删除的过程。当rear追到front时就表示队列已经满了,当front追上rear时就表示队列已经空了。

循环队列的实现过程

一般情况下,会少用一个元素空间,即队列空间大小为m时,有m-1个元素就认为是队满。这样当头尾指针的值相同时,则认为对空;当尾指针在循环意义上加1后是等于头指针,则认为队满。

当添加一个元素时,(queue.rear + 1) % maxSize;

当删除一个元素时,(queue.front + 1) % maxSize;

队空的条件:queue.front == queue.rear    //当队列添加元素到rear的下一个元素是队头的时候,也就是转圈子要碰头了,我们就认为队列满了。

队满的条件:(queue.rear + 1) % maxSize == queue.front    //当队列删除元素到head=rear的时候,我们认为队列空了。

循环队列的代码实现

package 循环队列;

public class LoopQueue {

	int front;
int rear;
int maxSize;
Object queueList[]; //初始化队列
public LoopQueue() {
maxSize = 1024;
queueList = new Object[maxSize];
rear = 0;
front = 0;
} //初始化队列
public LoopQueue(int maxSize) {
this.maxSize = maxSize;
queueList = new Object[maxSize];
rear = 0;
front = 0;
}
//判断队列是否为空
public boolean isEmpty() {
return this.front == this.rear ? true : false;
} //判断队列是否已满
public boolean isFull() {
return ((rear + 1) % this.maxSize) == this.front ? true : false;
} //取循环队列的对头元素
public Object getFront() {
if(isEmpty() == false) return queueList[this.front];
else {
System.out.println("ERROR:Queue is Empty");
return "";
}
} //入队
public void enQueue(Object e) {
if(isFull() == false) {
this.queueList[this.rear] = e;
this.rear = (this.rear + 1) % this.maxSize;
}
else System.out.println("ERROR::Queue is Full");
} //出队
public void deQueue() {
if(isEmpty() == false) {
this.front = (this.front + 1) % this.maxSize;
}
else System.out.println("ERROR::Queue is empty");
} //获取队列长度
public int QueueLength() {
return (this.rear - this.front + this.maxSize) % this.maxSize;
} public static void main(String[] args) {
LoopQueue q = new LoopQueue();
System.out.println("队列是否为空:" + q.isEmpty());
System.out.println("队列是否为满:" + q.isFull());
System.out.println("队列长度:" + q.QueueLength());
q.enQueue(5);
q.enQueue(4);
q.enQueue(3);
q.enQueue(2);
q.enQueue(1);
System.out.println("队列长度:" + q.QueueLength());
q.deQueue();
System.out.println("队列是否为空:" + q.isEmpty());
System.out.println("对头元素:" + q.getFront());
System.out.println("队列长度:" + q.QueueLength());
} }

队列的理解和实现(一) ----- 循环队列(java实现)的更多相关文章

  1. <数据结构系列3>队列的实现与变形(循环队列)

    数据结构第三课了,今天我们再介绍一种很常见的线性表——队列 就像它的名字,队列这种数据结构就如同生活中的排队一样,队首出队,队尾进队.以下一段是百度百科中对队列的解释: 队列是一种特殊的线性表,特殊之 ...

  2. 队列的理解和实现(二) ----- 链队列(java实现)

    什么是链队列 链队是指采用链式存储结构实现的队列,通常链队用单链表俩表示.一个链队显然需要两个分别指示队头和队尾的指针,也称为头指针和尾指针,有了这两个指针才能唯一的确定. package 链队列; ...

  3. [从今天开始修炼数据结构]队列、循环队列、PriorityQueue的原理及实现

    [从今天开始修炼数据结构]基本概念 [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList [从今天开始修炼数据结构]栈.斐波那契数列.逆波兰四则运 ...

  4. leetcode622. 设计循环队列

    设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为“环形缓冲器”. 循环队列的一个好处是我们可以利用这个队列 ...

  5. 使用 JavaScript 实现基本队列、优先队列和循环队列

    1.基本队列的实现 基本队列的方法中,包含了 ①向队列(尾部)中添加元素(enqueue).②(从队列头部)删除元素(dequeue).③查看队列头部的元素(front).④查看队列是否为空(isEm ...

  6. 循环队列+堆优化dijkstra最短路 BZOJ 4152: [AMPPZ2014]The Captain

    循环队列基础知识 1.循环队列需要几个参数来确定 循环队列需要2个参数,front和rear 2.循环队列各个参数的含义 (1)队列初始化时,front和rear值都为零: (2)当队列不为空时,fr ...

  7. Javascript数据结构与算法--队列(顺序队列、优先队列、循环队列)的实现与用法

    前言 队列和栈非常类似,前面已经讲过了栈的实现与用法,现在我们来说说队列. 队列介绍 队列遵循FIFO(First In First Out,先进先出)原则的一组有序的项. 队列是一种特殊的线性表,特 ...

  8. [Swift]LeetCode622. 设计循环队列 | Design Circular Queue

    Design your implementation of the circular queue. The circular queue is a linear data structure in w ...

  9. 622.设计循环队列 javascript实现

    设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为“环形缓冲器”. 循环队列的一个好处是我们可以利用这个队列 ...

随机推荐

  1. ios7 导航栏适配

    ios ui开发过程中,经常会使用到导航栏,默认的样式比较单一,所以经常需要修改导航栏的样式 ios4: - (void)drawRect:(CGRect)rect { UIImage *image ...

  2. RabbitMQ学习在windows下安装配置

    RabbitMQ学习一. 在windows下安装配置 1.下载并安装erlang,http://www.erlang.org/download.html,最新版是R15B01(5.9.1).由于我机器 ...

  3. gatttool的使用

    1.使能hci接口 # hciconfig hci0 up 2.使用hcitool搜索BLE设备 # hcitool lescan LE Scan ...D0:39:72:BE:D2:26 (unkn ...

  4. Android布局属性说明

    Android布局LinearLayout注意设置属性android:orientation属性,否则有的组件可能无法显示. 该属性不设置时默认为horizontal.此时第一个控件的宽度若设置成“f ...

  5. Python中ndarray数组切片问题a[-n -x:-y]

    先看看如下代码: >>a=np.arange(10)>>a array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>a[-7:] array( ...

  6. 08 Translating RNA into Protein

    Problem The 20 commonly occurring amino acids are abbreviated by using 20 letters from the English a ...

  7. CMD 与 ENTRYPOINT 的区别

    Dockerfile里有 CMD 与 ENTRYPOINT 两个功能咋看起来很相似的指令,开始的时候觉得两个互用没什么所谓,但其实并非如此: CMD指令: The main purpose of a ...

  8. 第二届CCCC赛后感想 2017-04-15 23:56 88人阅读 评论(0) 收藏

    第一次写赛后感想,也不算什么很正规的比赛,不过这次比赛的时间恰好处于思想变化的阶段,留贴纪念. 先谈谈这次比赛,弱校萌新,依靠申请进了总决赛,发现和第一届不一样,缺少了团队奖心中有点缺乏动力,比赛2个 ...

  9. Oracle Alert - APP-ALR-04108: SQL error ORA-01455

    SELECT OD.ORGANIZATION_CODE, TO_CHAR(H.ORDER_NUMBER), --ORACLE ALERT 自动转数字类型最长11位,转字符处理解决APP-ALR-041 ...

  10. Cockroachdb 四、用户管理及授权

    四 用户管理及授权 用户管理 简介# Create a user:cockroach user set <username> <flags> # List all users: ...