数据结构之循环队列[Java]

超、凢脫俗 2023-07-22 05:56 116阅读 0赞
  1. /** * @ClassName: LoopQueue * @Author: Leo * @Description: 循环队列 * @Date: 4/4/2020 4:35 PM */
  2. public class LoopQueue<E> implements Queue<E> {
  3. //存放元素的数组
  4. private E[] data;
  5. //队首引用 队尾引用
  6. private int front, tail;
  7. //队列元素数量
  8. private int size;
  9. public LoopQueue(int capacity) {
  10. data = (E[]) new Object[capacity + 1];
  11. front = 0;
  12. tail = 0;
  13. size = 0;
  14. }
  15. public LoopQueue() {
  16. this(10);
  17. }
  18. /** * 获取队列容积 * * @return */
  19. public int getCapacity() {
  20. return data.length - 1;
  21. }
  22. /** * 获取队列元素数量 * * @return */
  23. @Override
  24. public int getSize() {
  25. return size;
  26. }
  27. /** * 判断队列是否为空 * * @return */
  28. @Override
  29. public boolean isEmpty() {
  30. //首尾引用相等 证明队列为空 如果(tail + 1) % data.length == front 则队列满
  31. return front == tail;
  32. }
  33. /** * 入队 * * @param e */
  34. @Override
  35. public void enqueue(E e) {
  36. //如果队列满 则扩容两倍
  37. if ((tail + 1) % data.length == front) {
  38. resize(getCapacity() * 2);
  39. }
  40. //把元素添加到队尾
  41. data[tail] = e;
  42. //队尾指针后移一位
  43. tail = (tail + 1) % data.length;
  44. size++;
  45. }
  46. /** * 扩容 * * @param newCapacity */
  47. private void resize(int newCapacity) {
  48. //新建一个指定容量的数组
  49. E[] newData = (E[]) new Object[newCapacity + 1];
  50. //把之前数组的元素复制到新数组
  51. for (int i = 0; i < size; i++) {
  52. //偏移量为front
  53. newData[i] = data[(i + front) % data.length];
  54. }
  55. data = newData;
  56. front = 0;
  57. tail = size;
  58. }
  59. /** * 出队 * * @return */
  60. @Override
  61. public E dequeue() {
  62. if (isEmpty()) {
  63. throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
  64. }
  65. //暂存出队元素
  66. E e = data[front];
  67. data[front] = null;
  68. //头引用+1
  69. front = (front + 1) % data.length;
  70. size--;
  71. //如果元素数量为容积的1/4 则缩容为原来的1/2
  72. if (size == getCapacity() / 4 && getCapacity() / 2 != 0) {
  73. resize(getCapacity() / 2);
  74. }
  75. return e;
  76. }
  77. /** * 获取队首元素 * * @return */
  78. @Override
  79. public E getFront() {
  80. if (isEmpty()) {
  81. throw new IllegalArgumentException("Queue is empty.");
  82. }
  83. return data[front];
  84. }
  85. @Override
  86. public String toString() {
  87. StringBuilder res = new StringBuilder();
  88. res.append(String.format("Queue: size = %d , capacity = %d\n", size, getCapacity()));
  89. res.append("Front [");
  90. for (int i = front; i != tail; i = (i + 1) % data.length) {
  91. res.append(data[i]);
  92. if ((i + 1) % data.length != tail) {
  93. res.append(", ");
  94. }
  95. }
  96. res.append("] Tail");
  97. return res.toString();
  98. }
  99. }

发表评论

表情:
评论列表 (有 0 条评论,116人围观)

还没有评论,来说两句吧...

相关阅读

    相关 数据结构循环队列

    循环队列的设计是为了避免“虚溢出”的现象。所谓“虚溢出”是指在利用数组构建队列时,当尾指针指向数组末尾时,即便数组前端仍有剩余空间,但是却无法向队列中添加新元素的“虚假溢出”的