循环数组的另一种实现

循环数组的另一种实现

已经介绍过一个 循环数组,这里介绍另一种实现方法。

参考: Implementing a Ring Buffer in Java


 1/**
 2 * 队列的循环数组另一种实现,参考:
 3 * <a href="https://www.baeldung.com/java-ring-buffer">
 4 * Implementing a RingBuffer in Java</a>
 5 *
 6 * <p>
 7 * 这种方法的解决思路是:
 8 * <ul>
 9 * <li>
10 * 1.
11 * 引入2个变量,{@link CircularBufferVariety#readSequence}和
12 * {@link CircularBufferVariety#writeSequence},
13 * 分别记录元素入队和出队的次数;初始化时,readSequence = 0, writeSequence =
14 * -1;writeSequence=-1的好处在于其实际上
15 * 相当于<b>直接指向</b>了队列队尾元素的index;
16 * </li>
17 * <li>
18 * 2. 为了循环使用数组中的slot,可以使用<code>writeSequence % N</code>取模
19 * 的方式找到当前队列队尾的元素对应的index;
20 * </li>
21 * <li>
22 * 3. 当readSequence > writeSequence时,即可认为队列为空;
23 * </li>
24 * <li>
25 * 4. 当(writeSequence - readSequence)+ 1 ==
26 * {@link CircularBufferVariety#data}.length时,即可认为队列已满;
27 * </li>
28 * </ul>
29 *
30 * @author wangy
31 * @version 1.0
32 * @date 2021/7/1 / 14:53
33 * @see CircularBuffer
34 */
35public class CircularBufferVariety {
36    private int[] data;
37    // 出队次数
38    private int readSequence;
39    // 入队次数
40    private int writeSequence;
41    // 队列中元素的个数,等于 writeSequence - readSequence + 1
42    private int count;
43
44    public CircularBufferVariety(int cap) {
45        this.data = new int[cap];
46        this.readSequence = 0;
47        this.writeSequence = -1;
48        this.count = 0;
49    }
50
51    boolean isEmpty() {
52        return readSequence > writeSequence;
53    }
54
55    boolean isFull() {
56        return writeSequence - readSequence + 1 == data.length;
57    }
58
59    int enQueue(int e) {
60        if (isFull())
61            throw new RuntimeException("Queue full!");
62        data[++writeSequence % data.length] = e;
63        return e;
64    }
65
66    int deQueue() {
67        if (isEmpty())
68            throw new RuntimeException("Queue empty!");
69        return data[readSequence++ % data.length];
70    }
71
72    void printAll() {
73        System.out.println("数组:" + Arrays.toString(data));
74        System.out.print("队列:[");
75        // 从队头到队尾
76        for (int i = readSequence; i <= writeSequence; i++) {
77            System.out.print(data[i % data.length] + " ");
78        }
79        System.out.println("]");
80    }
81
82    public static void main(String[] args) {
83        CircularBufferVariety cb = new CircularBufferVariety(4);
84        cb.enQueue(1);
85        cb.deQueue();
86        cb.enQueue(2);
87        cb.enQueue(3);
88        cb.enQueue(5);
89        cb.deQueue();
90        cb.enQueue(7);
91        cb.printAll();
92        cb.enQueue(9);
93        cb.printAll();
94        // full exception
95        cb.enQueue(11);
96    }
97}