本文根据《大话数据结构》一书,实现了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

  实现程序:

  1. /**
  2. * <循环队列>
  3. *
  4. * 注意点:表长的表示、队列满的判断、front和rear的改变
  5. *
  6. * @author Lai
  7. *
  8. */
  9. public class SqQueue<E> {
  10. private E[] data;
  11. private int front;
  12. private int rear;
  13. private int maxSize;
  14. private static final int DEFAULT_SIZE= 10;
  15.  
  16. /*
  17. * 初始化
  18. */
  19. public SqQueue(){
  20. this(DEFAULT_SIZE);
  21. }
  22. public SqQueue(int maxSize){
  23. data=(E[]) new Object[maxSize];
  24. this.maxSize=maxSize;
  25. front=0;
  26. rear=0;
  27. }
  28.  
  29. /*
  30. * 求循环队列长度
  31. */
  32. public int getLength() {
  33. return (rear-front+maxSize)%maxSize;
  34. }
  35.  
  36. /*
  37. * 入队操作
  38. */
  39. public void enQueue(E e) {
  40. if((rear+1)%maxSize==front)
  41. throw new RuntimeException("队列已满,无法入队!");
  42. data[rear]=e;
  43. rear=(rear+1)%maxSize;
  44. //不是rear=rear+1,当rear在数组尾部时,后移一位会转到数组头部
  45. }
  46.  
  47. /*
  48. * 出队操作
  49. */
  50. public E deQueue() {
  51. if(rear==front)
  52. throw new RuntimeException("队列为空!");
  53. E e=data[front];
  54. front=(front+1)%maxSize;
  55. //不是front++,理由同rear
  56. return e;
  57. }
  58.  
  59. /*
  60. * 打印操作
  61. */
  62. public void printQueue() {
  63. int k=front;
  64. for(int i=0;i<getLength();i++) {
  65. System.out.print(data[k]+" ");
  66. k=(k+1)%maxSize;
  67. }
  68. System.out.println();
  69. }
  70.  
  71. /*
  72. * 测试代码
  73. */
  74. public static void main(String[] args) {
  75. SqQueue<String> aQueue=new SqQueue<>(5);
  76. aQueue.enQueue("a");
  77. aQueue.enQueue("b");
  78. aQueue.enQueue("c");
  79. aQueue.enQueue("d");
  80. aQueue.printQueue();
  81. System.out.println("-----");
  82. aQueue.getLength();
  83. aQueue.deQueue();
  84. aQueue.deQueue();
  85. aQueue.enQueue("e");
  86. aQueue.printQueue();
  87. }
  88.  
  89. }

  

  1. a b c d
  2. -----
  3. c d e

SqQueue

2.队列的链式存储结构

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

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

    

  实现程序:

  1. /**
  2. * 链队列
  3. *
  4. * 注意点:出队操作时,若队头是队尾(即队中仅有一个结点),则删除后要将rear指向头结点。
  5. *
  6. * @author Yongh
  7. *
  8. * @param <E>
  9. */
  10. public class LinkQueue<E> {
  11. private QNode front,rear;
  12. private int count;
  13.  
  14. class QNode{
  15. E data;
  16. QNode next;
  17. public QNode(E data,QNode next) {
  18. this.data=data;
  19. this.next=next;
  20. }
  21. }
  22.  
  23. public LinkQueue() {
  24. front=new QNode(null, null);
  25. rear=front;
  26. count=0;
  27. }
  28.  
  29. /*
  30. * 入队操作
  31. */
  32. public void enQueue(E e) {
  33. QNode node=new QNode(e, null);
  34. rear.next=node;
  35. rear=node;
  36. count++;
  37. }
  38.  
  39. /*
  40. * 出队操作
  41. */
  42. public E deQueue() {
  43. if(rear==front)
  44. throw new RuntimeException("队列为空!");
  45. QNode node=front.next;
  46. E e=node.data;
  47. front.next=node.next;
  48. //若队头是队尾,则删除后要将rear指向头结点。
  49. if(rear==node)
  50. rear=front;
  51. node=null;
  52. count--;
  53. //通过count来判断,可能更容易理解
  54. //if(count==0)
  55. // rear=front;
  56. return e;
  57. }
  58.  
  59. /*
  60. * 获取队列长度
  61. */
  62. public int getLength() {
  63. return count;
  64. }
  65.  
  66. /*
  67. * 打印输出队列
  68. */
  69. public void printQueue() {
  70. if(count==0) {
  71. System.out.println("空队列");
  72. }else {
  73. QNode node=front;
  74. for(int i=0;i<count;i++) {
  75. node=node.next;
  76. System.out.print(node.data+" ");
  77. }
  78. System.out.println();
  79. }
  80. }
  81.  
  82. /*
  83. * 测试代码
  84. */
  85. public static void main(String[] args) {
  86. LinkQueue<String> lQueue =new LinkQueue<>();
  87. lQueue.printQueue();
  88. lQueue.enQueue("A");
  89. lQueue.enQueue("B");
  90. lQueue.enQueue("c");
  91. lQueue.enQueue("D");
  92. lQueue.printQueue();

  93. lQueue.deQueue();
  94. lQueue.deQueue();
  95. lQueue.enQueue("E");
  96. lQueue.printQueue();
  97. }
  98. }

  

  1. 空队列
  2. A B c D
  3. 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. 如何设置Java虚拟机JVM启动内存参数

    Tomcat默认的Java虚拟机JVM启动内存参数大约只有64MB或者128MB,非常小,远远没有利用现在服务器的强大内存,所以要设置Java虚拟机JVM启动内存参数.具体设置方法为: Tomcat修 ...

  2. 【BZOJ3489】A simple rmq problem(KD-Tree)

    [BZOJ3489]A simple rmq problem(KD-Tree) 题面 BZOJ 题解 直接做肯定不好做,首先我们知道我们是一个二维平面数点,但是限制区间只能出现一次很不好办,那么我们给 ...

  3. Hadoop实战:Hadoop分布式集群部署(一)

    一.系统参数优化配置 1.1 系统内核参数优化配置 修改文件/etc/sysctl.conf,使用sysctl -p命令即时生效.   1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  4. .net 未被引用的错误

    开发的时候遇到了一个错误,如下: 错误 1 类型“System.ServiceModel.ClientBase`1<T0>”在未被引用的程序集中定义. 我原本以为是版本号的问题,添加了引用 ...

  5. npm install --save

    1. npm install:本地安装 2. npm install -g:全局安装 我们在使用 npm install 安装模块或插件时,有两种命令把它们写入到 package.json 文件中去, ...

  6. mybatis dao 层开发简易版 非整合 spring

    同样老习惯,先上项目结构截图 首先 补充上篇文中缺失的 mysql demo 用的 小脚本 drop database if exists mybatis; CREATE DATABASE `myba ...

  7. mongodb的认证(authentication)与授权(authorization)

    一小白瞎整mongodb,认证部分被折磨的惨不忍睹,看厮可怜,特查了一下文档,浅显地总结一下mongodb认证(authentication)与授权(authorization)的联系. 创建的所有用 ...

  8. 重启sqlserver服务 命令

    在控制台(CMD)中运行: net stop mssqlserver     net start mssqlserver

  9. shell 示例1 从1叠加到100

    从1叠加到100 echo $[$(echo +{..})] echo $[(+)*(/)] seq -s |bc

  10. ViewGroup.layout(int l, int t, int r, int b)四个输入参数的含义

    ViewGroup.layout(int l, int t, int r, int b)这个方法是确定View的大小和位置的,然后将其绘制出来,里面的四个参数分别是View的四个点的坐标,他的坐标不是 ...