本文根据《大话数据结构》一书,实现了Java版的循环队列、链队列

队列:只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

1.循环队列

  队列的顺序储存结构:用数组存储队列,引入front指针指向队头元素,rear指针指向队尾元素的下一个位置,当front=rear时,为空队列,结构如下图所示。

 

  当执行入队操作时,若数组尾部已满,而数组前部因有元素出队而有空位时,我们把新插入的元素从头开始入队,这样就类似于头尾相接的结构。

  队列的这种头尾相接的顺序存储结构称为循环队列,如下图所示。

  上面队列的定义中提到,当front=rear时,为空队列,而在循环队列中,队列满时,front也等于rear,将无法判断队满和空的情况。

    一种办法是设置一个标志变量flag,当front=rear时,通过判断flag是0还是1来确定队列满空情况;

    另一种方法是,在数组中只剩一个空闲单位时,定义为队列满,如下图所示。(本文程序采用这种办法)

  因为rear可能比front大,也可能比front小,所以队列满的条件应该为:(rear+1)%maxSize==front;同理,队列长度的计算公式为:(rear-front+maxSize)%maxSize

  实现程序:

/**
* <循环队列>
*
* 注意点:表长的表示、队列满的判断、front和rear的改变
*
* @author Lai
*
*/
public class SqQueue<E> {
private E[] data;
private int front;
private int rear;
private int maxSize;
private static final int DEFAULT_SIZE= 10; /*
* 初始化
*/
public SqQueue(){
this(DEFAULT_SIZE);
}
public SqQueue(int maxSize){
data=(E[]) new Object[maxSize];
this.maxSize=maxSize;
front=0;
rear=0;
} /*
* 求循环队列长度
*/
public int getLength() {
return (rear-front+maxSize)%maxSize;
} /*
* 入队操作
*/
public void enQueue(E e) {
if((rear+1)%maxSize==front)
throw new RuntimeException("队列已满,无法入队!");
data[rear]=e;
rear=(rear+1)%maxSize;
//不是rear=rear+1,当rear在数组尾部时,后移一位会转到数组头部
} /*
* 出队操作
*/
public E deQueue() {
if(rear==front)
throw new RuntimeException("队列为空!");
E e=data[front];
front=(front+1)%maxSize;
//不是front++,理由同rear
return e;
} /*
* 打印操作
*/
public void printQueue() {
int k=front;
for(int i=0;i<getLength();i++) {
System.out.print(data[k]+" ");
k=(k+1)%maxSize;
}
System.out.println();
} /*
* 测试代码
*/
public static void main(String[] args) {
SqQueue<String> aQueue=new SqQueue<>(5);
aQueue.enQueue("a");
aQueue.enQueue("b");
aQueue.enQueue("c");
aQueue.enQueue("d");
aQueue.printQueue();
System.out.println("-----");
aQueue.getLength();
aQueue.deQueue();
aQueue.deQueue();
aQueue.enQueue("e");
aQueue.printQueue();
} }

  

a b c d
-----
c d e

SqQueue

2.队列的链式存储结构

  用单链表存储队列,称为链队列

  定义front指针指向头结点,rear指针指向终端结点,空队列时,front和rear都指向头结点。

    

  实现程序:

/**
* 链队列
*
* 注意点:出队操作时,若队头是队尾(即队中仅有一个结点),则删除后要将rear指向头结点。
*
* @author Yongh
*
* @param <E>
*/
public class LinkQueue<E> {
private QNode front,rear;
private int count; class QNode{
E data;
QNode next;
public QNode(E data,QNode next) {
this.data=data;
this.next=next;
}
} public LinkQueue() {
front=new QNode(null, null);
rear=front;
count=0;
} /*
* 入队操作
*/
public void enQueue(E e) {
QNode node=new QNode(e, null);
rear.next=node;
rear=node;
count++;
} /*
* 出队操作
*/
public E deQueue() {
if(rear==front)
throw new RuntimeException("队列为空!");
QNode node=front.next;
E e=node.data;
front.next=node.next;
//若队头是队尾,则删除后要将rear指向头结点。
if(rear==node)
rear=front;
node=null;
count--;
//通过count来判断,可能更容易理解
//if(count==0)
// rear=front;
return e;
} /*
* 获取队列长度
*/
public int getLength() {
return count;
} /*
* 打印输出队列
*/
public void printQueue() {
if(count==0) {
System.out.println("空队列");
}else {
QNode node=front;
for(int i=0;i<count;i++) {
node=node.next;
System.out.print(node.data+" ");
}
System.out.println();
}
} /*
* 测试代码
*/
public static void main(String[] args) {
LinkQueue<String> lQueue =new LinkQueue<>();
lQueue.printQueue();
lQueue.enQueue("A");
lQueue.enQueue("B");
lQueue.enQueue("c");
lQueue.enQueue("D");
lQueue.printQueue();

lQueue.deQueue();
lQueue.deQueue();
lQueue.enQueue("E");
lQueue.printQueue();
}
}

  

空队列
A B c D
c D E

LinkQueue

3.循环队列和链队列的选择

  基本操作时间都为O(1)。但链队列每次申请和释放结点会存在一点时间开销,且其需要存储一个指针域;而循环队列必须固定空间长度,存在空间浪费问题,且没链队列灵活。

  综上,在可以确定队列长度最大值的情况下,建议用循环队列;当无法预估队列的长度时,使用链队列

【Java】 大话数据结构(7) 循环队列和链队列的更多相关文章

  1. java实现 数据结构:链表、 栈、 队列、优先级队列、哈希表

    java实现 数据结构:链表. 栈. 队列.优先级队列.哈希表   数据结构javavector工作importlist 最近在准备找工作的事情,就复习了一下java.翻了一下书和网上的教材,发现虽然 ...

  2. C语言——循环队列和链队列的基本运算

    // 循环队列#include <stdio.h> #include "SeqQue.h" // 循环队列的基本运算 /* const int maxsize = 20 ...

  3. JAVA该队列中的数组,圆阵队列,链队列

    /** * 文件名:QueueText.java * 时间:2014年10月22下午9:05:13 * 笔者:维亚康姆维修 */ package chapter3; /** * 类名:ArrayQue ...

  4. java:数据结构复习(三)链表队列

    @TOC 和栈一样,队列也是表,但是使用队列的特点是先进先出. 队列模型 队列的基本操作是入队,它是在表的末端插入一个元素,和出队,它是删除在表开头的一个元素 graph LR A[<kbd&g ...

  5. 大话数据结构(十)java程序——队列

    1.队列的定义 队列(queue):是只允许在一端进行插入操作,而在另一端进行删除操作的线性表. 队列是一种先进先出的线性表,简称FIFO(First out firts in).允许插入的一头是队尾 ...

  6. java 基础数据结构

    数据结构, 需要考虑两个方面: 1. 每个元素具体的存储方法 (java中是一个对象) 2. 元素之间的关系如何实现存储 (java中也是一个对象) 另外在java中, 已经可以把跟数据结构有关的一些 ...

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

    一.队列的概念: 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其 ...

  8. 【Java】 大话数据结构(6) 栈的顺序与链式存储

    本文根据<大话数据结构>一书,实现了Java版的栈的顺序存储结构.两栈共享空间.栈的链式存储机构. 栈:限定仅在表尾进行插入和删除操作的线性表. 栈的插入(进栈)和删除(出栈)操作如下图所 ...

  9. 数据结构----队列:顺序队列&顺序循环队列、链式队列、顺序优先队列

    一.队列的概念: 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其 ...

随机推荐

  1. Oracle中对number类型数据to_char()出现各位少0,或者值为###的处理

    问题描述: 在Oracle中使用to_char()函数时当number值为小数时,常常个位0不显示 比如:select to_char(0.02) from dual,结果为.02 改进为 selec ...

  2. Libre 6003 「网络流 24 题」魔术球 (网络流,最大流)

    Libre 6003 「网络流 24 题」魔术球 (网络流,最大流) Description 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为 1,2,3,4......的球. (1)每次只 ...

  3. github使用记录

    背景:一直以来,对github既向往又排斥,是因为感觉高大尚有感觉很陌生.现在跟着辉哥学习项目技术,打算好好的学习下这个工具的使用. 1 基础常识 1.1 基础讲解 star的作用是收藏,目的是方便以 ...

  4. 8: springMVC ModelAndView 作用与功能解析

    Spring mvc视图机制 所有的web应用的mvc框架都有它定位视图的方式.Spring提供了视图解析器供你在浏览器中显示模型数据,而不必被拘束在特定的视图技术上. Spring的控制器Contr ...

  5. vue-devtools/安装vue-devtools

    一.在github上下载压缩包,github下载地址:https://github.com/vuejs/vue-devtools 二.解压到本地的某盘 三.用你的npm中进入该文件夹下 在npm中执行 ...

  6. scrapy 让指定的spider执行指定的pipeline

    处理scrapy中包括多个pipeline时如何让spider执行制定的pipeline管道1:创建一个装饰器from scrapy.exceptions import DropItemimport ...

  7. 鸟哥的Linux私房菜——第十四章:Bash Shell

    视频链接:http://www.bilibili.com/video/av10094012/ 本章目录: 1. Bash shell1.1 什么是 shell ? (我们通过shell与Kernel核 ...

  8. 从url到页面加载浏览器做了什么?

    从输入url到页面加载发生了什么?1.DNS解析DNS解析是一个递归查询的过程.DNS解析的过程就是寻找哪台机器上有你需要资源的过程,当你在浏览器中输入一个地址时,www.baidu.com.其实不是 ...

  9. 【GDOI2018】所有题目和解题报告

    使用说明:题意和数据范围都只是回忆内容,仅供参考.题解陆续补上. Day 1 第一题 题意:给定n个数字,要求划分成k的连续段使得每个连续段内的数字之和相同,求最大的k.n,Σai<=10^6. ...

  10. C. NN and the Optical Illusion(几何)

    题目链接:http://codeforces.com/contest/1100/problem/C 题目大意:给你n和r,n指的是有n个圆围在里面的圆的外面,r指的是里面的圆的半径,然后让你求外面的圆 ...