// 8. hét – Ciklikus sor (körkörös puffer) tömbbel
// Futtatás: java CircularQueue.java
public class CircularQueue {
    private final int[] data;
    private int front = 0; // az első elem indexe
    private int rear = -1; // az utolsó elem indexe
    private int count = 0; // az elemek száma – ebből dönthető el az üres / tele állapot

    CircularQueue(int capacity) { data = new int[capacity]; }

    boolean isEmpty() { return count == 0; }
    boolean isFull() { return count == data.length; }

    // Betétel a sor végére – O(1)
    //   Pszeudokód:  Ha Tele akkor HIBA ; vége ← (vége + 1) mod n ; T[vége] ← x ; db ← db + 1
    void enqueue(int x) {
        if (isFull()) throw new IllegalStateException("a sor megtelt");
        rear = (rear + 1) % data.length; // körbefordulás a tömb végén
        data[rear] = x;
        count++;
    }

    // Kivétel a sor elejéről – O(1)
    //   Pszeudokód:  Ha Üres akkor HIBA ; x ← T[eleje] ; eleje ← (eleje + 1) mod n ; db ← db − 1
    int dequeue() {
        if (isEmpty()) throw new IllegalStateException("a sor üres");
        int x = data[front];
        front = (front + 1) % data.length;
        count--;
        return x;
    }

    int peek() {
        if (isEmpty()) throw new IllegalStateException("a sor üres");
        return data[front];
    }

    public String toString() {
        StringBuilder sb = new StringBuilder("[eleje] ");
        for (int i = 0; i < count; i++) sb.append(data[(front + i) % data.length]).append(' ');
        return sb.append("[vége]  (front=" + front + ", rear=" + rear + ", count=" + count + ")").toString();
    }

    public static void main(String[] args) {
        CircularQueue q = new CircularQueue(5);
        for (int x = 1; x <= 5; x++) q.enqueue(x * 10);
        System.out.println("5 × enqueue:  " + q);
        try {
            q.enqueue(60);
        } catch (IllegalStateException e) {
            System.out.println("Hiba: " + e.getMessage());
        }
        System.out.println("dequeue() = " + q.dequeue() + ", dequeue() = " + q.dequeue());
        System.out.println("2 × dequeue:  " + q);
        q.enqueue(60);
        q.enqueue(70); // a rear körbefordul a tömb elejére
        System.out.println("2 × enqueue:  " + q);

        System.out.print("kiürítés (FIFO sorrend): ");
        while (!q.isEmpty()) System.out.print(q.dequeue() + " ");
        System.out.println();

        // Beépített sor: ArrayDeque (ciklikus tömb) vagy LinkedList
        java.util.Queue<String> jq = new java.util.ArrayDeque<>();
        jq.offer("Li");
        jq.offer("Wang");
        jq.offer("Chen");
        System.out.println("Queue: peek = " + jq.peek() + ", poll = " + jq.poll() + ", maradék = " + jq);
    }
}
