当前位置:   article > 正文

Java队列-queue_java queue全部出列

java queue全部出列

1. 使用场景

银行排队的案例:

2. 基本介绍

  • 队列是一个有序列表,可以用数组或是链表来实现。
  • 遵循先入先出的原则。即先存入队列的数据,要先取出;后存入的要后取出。

3. 数组模拟队列

思路

队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图, 其中 maxSize 是该队列的最大容量。  

因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front 和 rear 分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear 则是随着数据输入而改变,如图所示: 

当我们将数据存入队列时称为"addQueue",addQueue 的处理需要有两个步骤:思路分析

1) 将尾指针往后移:rear+1 , 当 front == rear 【空】

2) 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear 所指的数组元素中,否则无法存入数据。rear == maxSize - 1 [队列满]

不足

  • 数组只能使用一次,当队列中的数据取出后,并不能复用之前用过的空间。
  • 优化参考环形队列

实现

  • 添加元素,改变队尾指针 rear 的值;
  • 移出元素,改变队头指针 front 的值;
  • 其他操作不改变队头队尾的值,只在值基础上运算(取出队头为:front + 1)

数组队列

  1. package com.zsy.datastructure.queue;
  2. /**
  3. * 使用数组模拟队列
  4. *
  5. * @author zhangshuaiyin
  6. */
  7. public class ArrayQueue {
  8. /**
  9. * 队列最大空间
  10. */
  11. private int maxSize;
  12. /**
  13. * front: 指向队列头的前一个位置,用于标识队列头
  14. * rear:指向队列尾部
  15. */
  16. private int front;
  17. private int rear;
  18. private int[] array;
  19. public ArrayQueue(int arrayMaxSize) {
  20. maxSize = arrayMaxSize;
  21. array = new int[maxSize];
  22. front = -1;
  23. rear = -1;
  24. }
  25. /**
  26. * @return 判断队列是否为空
  27. */
  28. public boolean isEmpty() {
  29. return front == rear;
  30. }
  31. /**
  32. * @return 判断队列是否已满
  33. */
  34. public boolean isFull() {
  35. return rear == maxSize - 1;
  36. }
  37. /**
  38. * 向队列添加元素
  39. *
  40. * @param item 元素
  41. */
  42. public void add(int item) {
  43. if (isFull()) {
  44. System.out.println("队列已满,不能添加元素~~");
  45. return;
  46. }
  47. // rear 后移,新增一个存储空间
  48. rear++;
  49. array[rear] = item;
  50. }
  51. /**
  52. * 出队
  53. *
  54. * @return 头部数据
  55. */
  56. public int remove() {
  57. if (isEmpty()) {
  58. throw new RuntimeException("队列为空不能取出数据!!");
  59. }
  60. return array[++front];
  61. }
  62. /**
  63. * 打印队列中的元素
  64. */
  65. public void show() {
  66. if (isEmpty()) {
  67. System.out.println("The queue is empty.");
  68. return;
  69. }
  70. for (int i = 0; i < array.length; i++) {
  71. System.out.printf("arr[%d]=%d\n", i, array[i]);
  72. }
  73. }
  74. /**
  75. * 打印队列头部元素
  76. */
  77. public void head() {
  78. if (isEmpty()) {
  79. System.out.println("The queue is empty.");
  80. return;
  81. }
  82. System.out.println("head: " + array[front + 1]);
  83. }
  84. }

测试

  1. package com.zsy.datastructure.queue;
  2. import java.util.Scanner;
  3. /**
  4. * @author zhangshuaiyin
  5. */
  6. public class ArrayQueueTest {
  7. public static void main(String[] args) {
  8. ArrayQueue queue = new ArrayQueue(3);
  9. // 接收输入字符
  10. char key;
  11. Scanner scanner = new Scanner(System.in);
  12. boolean loop = true;
  13. while (loop) {
  14. System.out.println("****************");
  15. System.out.println("s(show): 显示队列");
  16. System.out.println("a(add): 添加数据");
  17. System.out.println("g(get): 取出数据");
  18. System.out.println("h(head): 头部数据");
  19. System.out.println("按其他任意键退出...");
  20. System.out.println("****************");
  21. key = scanner.next().charAt(0);
  22. switch (key) {
  23. case 's':
  24. queue.show();
  25. break;
  26. case 'a':
  27. System.out.println("请输入要添加队列的数字:");
  28. int value = scanner.nextInt();
  29. queue.add(value);
  30. break;
  31. case 'g':
  32. try {
  33. System.out.println("取出的数据:" + queue.remove());
  34. } catch (Exception e) {
  35. System.out.println(e.getMessage());
  36. }
  37. break;
  38. case 'h':
  39. queue.head();
  40. break;
  41. default:
  42. scanner.close();
  43. loop = false;
  44. System.out.println("程序退出~~");
  45. break;
  46. }
  47. }
  48. }
  49. }

4. 数组循环队列

参考《大话数据结构》

思路分析

  • front:指向队列的第一个元素,初始值为0;
  • rear:指向队列最后一个元素的下一个位置,且该位置为保留位,不会被数据占用;
  • 当队列满时,rear 应该指向 front 的前一个位置,即  (rear + 1) % maxSize == front();

  • 当队列为空时,front == rear,即出队时 front 后移,当移动到保留位置,表示队列空;
  • 队列中的元素个数:(rear - front + maxSize) % maxSize
    • 当rear > front,长度为:rear - front

    • 当 rear < front,长度为:(0 + rear) + (maxSize - front) = rear - front + maxSize

代码实现:

循环队列

  1. package com.zsy.datastructure.queue;
  2. /**
  3. * 数组实现循环队列
  4. *
  5. * @author zhangshuaiyin
  6. */
  7. public class CircleArrayQueue {
  8. /**
  9. * 数组最大长度,因为rear预留位,队列长度会少一位
  10. */
  11. private int maxSize;
  12. /**
  13. * front: 指向队列头一个元素
  14. */
  15. private int front;
  16. /**
  17. * rear: 指向队列最后一个元素的下一个位置
  18. * rear指向的位置为保留位,不会被元素占用
  19. */
  20. private int rear;
  21. private int[] array;
  22. public CircleArrayQueue(int arrayMaxSize) {
  23. this.maxSize = arrayMaxSize;
  24. array = new int[maxSize];
  25. this.front = this.rear = 0;
  26. }
  27. /**
  28. * @return 判断队列是否为空
  29. */
  30. public boolean isEmpty() {
  31. return front == rear;
  32. }
  33. /**
  34. * @return 判断队列是否已满
  35. */
  36. public boolean isFull() {
  37. return (rear + 1) % maxSize == front;
  38. }
  39. /**
  40. * 向队列添加元素
  41. *
  42. * @param item 元素
  43. */
  44. public void add(int item) {
  45. if (isFull()) {
  46. System.out.println("队列已满,不能添加元素~~");
  47. return;
  48. }
  49. array[rear] = item;
  50. // rear 后移,当移动到最后一个位置时,从 0 重新计数
  51. rear = (rear + 1) % maxSize;
  52. }
  53. /**
  54. * 出队
  55. *
  56. * @return 头部数据
  57. */
  58. public int remove() {
  59. if (isEmpty()) {
  60. throw new RuntimeException("队列为空不能取出数据!!");
  61. }
  62. // 取出数据为:array[front], 取出后 front 后移,当移动到最后一个位置时,从 0 重新计数
  63. int value = array[front];
  64. front = (front + 1) % maxSize;
  65. return value;
  66. }
  67. /**
  68. * 打印队列中的元素,从front开始到最后一个元素
  69. */
  70. public void show() {
  71. if (isEmpty()) {
  72. System.out.println("The queue is empty.");
  73. return;
  74. }
  75. for (int i = front; i < front + size(); i++) {
  76. System.out.printf("arr[%d]=%d\n", i % maxSize, array[i % maxSize]);
  77. }
  78. }
  79. /**
  80. * 打印队列头部元素
  81. */
  82. public void head() {
  83. if (isEmpty()) {
  84. System.out.println("The queue is empty.");
  85. return;
  86. }
  87. System.out.println("head: " + array[front]);
  88. }
  89. /**
  90. * @return 获取队列数据个数
  91. */
  92. public int size() {
  93. return (rear - front + maxSize) % maxSize;
  94. }
  95. }

测试

  1. package com.zsy.datastructure.queue;
  2. import java.util.Scanner;
  3. /**
  4. * @author zhangshuaiyin
  5. */
  6. public class CircleArrayQueueTest {
  7. public static void main(String[] args) {
  8. CircleArrayQueue queue = new CircleArrayQueue(3);
  9. // 接收输入字符
  10. char key;
  11. Scanner scanner = new Scanner(System.in);
  12. boolean loop = true;
  13. while (loop) {
  14. System.out.println("****************");
  15. System.out.println("s(show): 显示队列");
  16. System.out.println("a(add): 添加数据");
  17. System.out.println("g(get): 取出数据");
  18. System.out.println("h(head): 头部数据");
  19. System.out.println("按其他任意键退出...");
  20. System.out.println("****************");
  21. key = scanner.next().charAt(0);
  22. switch (key) {
  23. case 's':
  24. queue.show();
  25. break;
  26. case 'a':
  27. System.out.println("请输入要添加队列的数字:");
  28. int value = scanner.nextInt();
  29. queue.add(value);
  30. break;
  31. case 'g':
  32. try {
  33. System.out.println("取出的数据:" + queue.remove());
  34. } catch (Exception e) {
  35. System.out.println(e.getMessage());
  36. }
  37. break;
  38. case 'h':
  39. queue.head();
  40. break;
  41. default:
  42. scanner.close();
  43. loop = false;
  44. System.out.println("程序退出~~");
  45. break;
  46. }
  47. }
  48. }
  49. }

青山不改,绿水常流!谢谢大家

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号