当前位置:   article > 正文

数据结构之队列_队列数据结构

队列数据结构

什么是队列

队列(queue)是一种线性数据结构。与同为线性数据结构的栈不同的是队列中的元素遵循的是先进先出(First In First Out)的规则,和在现实中排队一样,讲究的是先来后到的原则。队列出口端叫做队头(front),队列的入口端叫做队尾(rear)。

与栈类似,队列这种线性数据结构既可以用数组来实现,也可以用链表来实现。用数组来实现时,我们可以自行规定队尾的位置,比如说规定最后一个元素的下一个位置为队尾,或者规定最后一个元素所在的位置为队尾,这两种都行,毕竟是自己实现的。本文规定最后一个元素的下一个位置为队尾。同时,本文采用数组来实现队列。

队列的链表实现如下:

队列的数组实现如下:

 我们使用元素 0 来进行占位。

队列的基本操作

队列的基本操作包括入队(enqueue)和出队(dequeue)两种。

1.入队

入队就是把新元素放入到队列中,只允许从队尾方向入队,入队之后,新元素的下一个元素所在的位置称为队尾。例如:一个已有元素3、5、1、4、9、6的队列,现需要将元素 7 进行入队,那么入队之后的新队列为:

2.出队

出队就是把元素从队头方向移出队列,只允许在队头一侧进行出队操作。出队之后,出队元素的新一个元素作为新的队头。例如:现有一个元素为3、5、1、4、9、6、7的队列,需要将队头元素 3 进行出队操作,那么出队之后新队列即为:

 很显然,队列的出队操作我们只是将队头元素的指向进行了移动,并没有将原有的队头元素进行删除,那这样的话就会导致出现一个问题,不删除原有元素,一直进行出队操作,导致队头左边的空间失去意义,如果不进行数组扩容的话,队列容量只会越来越小的。针对这种情况,便出现了一种特殊的队列——循环队列。

假设现有一个容量为 9 的队列,在经过一系列入队和出队操作之后只剩下了两个元素,这两个元素位于该队列的倒数第一和倒数第二的位置,即该队列已满,但此时有一个新元素需要入队,在不对数组进行扩容的前提下,我们可以让新的队尾指向该数组的首位,利用一下队列中已出队元素的空间。这样一来,整个队列的元素就循环起来了。在物理存储上,队尾的位置也可以在队头之前。当有新元素再次入队时,将其放入数组的首位,队尾继续后移即可。

 那么什么时候我们称该队列已满呢?按照我们的规定,队尾为最后一个元素所在的位置,即(队尾下标 + 1)% 数组长度 = 队头下标时,代表此队列已满,无法再进行入队操作。.因为队尾永远指向最后一个元素的下一个位置,所以队列的最大容量等于数组长度减1。如下所示便是队列已满的情况:

相关代码如下:

  1. package structure.queue;
  2. /**
  3. * @ClassName: Queue
  4. * @Author: jiaomubai
  5. * @Date: 2022/1/30 14:59
  6. * @Description:
  7. */
  8. public class Queue {
  9. private int[] dataArray;
  10. private int front;
  11. private int rear;
  12. public Queue(int capacity) {
  13. this.dataArray = new int[capacity];
  14. }
  15. public void enQueue(int element) {
  16. if ((rear + 1) % dataArray.length == front) {
  17. System.out.println("队已满");
  18. System.out.println();
  19. return;
  20. }
  21. dataArray[rear] = element;
  22. rear = (rear + 1) % dataArray.length;
  23. System.out.println("入队后队头元素为:" + dataArray[front]);
  24. System.out.println("入队后队尾元素为:" + element);
  25. System.out.println();
  26. }
  27. public int deQueue() {
  28. if (rear == front) {
  29. System.out.println("队已空");
  30. System.out.println();
  31. }
  32. int deQueueElement = dataArray[front];
  33. front = (front + 1) % dataArray.length;
  34. System.out.println("出队后队头元素为:" + dataArray[front]);
  35. System.out.println("出队后队尾元素为:" + dataArray[rear - 1]);
  36. System.out.println();
  37. return deQueueElement;
  38. }
  39. public void print() {
  40. for (int i = front; i != rear - 1; i = (i + 1) % dataArray.length) {
  41. System.out.print(dataArray[i] + " --> ");
  42. }
  43. System.out.println(dataArray[rear - 1]);
  44. System.out.println();
  45. }
  46. public static void main(String[] args) {
  47. Queue queue = new Queue(6);
  48. queue.enQueue(1);
  49. queue.enQueue(2);
  50. queue.enQueue(3);
  51. queue.enQueue(4);
  52. queue.enQueue(5);
  53. queue.enQueue(6);
  54. queue.print();
  55. queue.deQueue();
  56. queue.deQueue();
  57. queue.deQueue();
  58. queue.print();
  59. queue.enQueue(6);
  60. queue.enQueue(7);
  61. queue.print();
  62. }
  63. }

 上述代码执行结果为:

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/448947
推荐阅读
相关标签
  

闽ICP备14008679号